Что такое rowid в sql
For each row in the database, the ROWID pseudocolumn returns the address of the row. Oracle Database rowid values contain information necessary to locate a row:
- The data object number of the object
- The data block in the data file in which the row resides
- The position of the row in the data block (first row is 0)
- The data file in which the row resides (first file is 1). The file number is relative to the tablespace.
Usually, a rowid value uniquely identifies a row in the database. However, rows in different tables that are stored together in the same cluster can have the same rowid.
Values of the ROWID pseudocolumn have the data type ROWID or UROWID . Refer to Rowid Data Types and UROWID Data Type for more information.
Rowid values have several important uses:
- They are the fastest way to access a single row.
- They can show you how the rows in a table are stored.
- They are unique identifiers for rows in a table.
You should not use ROWID as the primary key of a table. If you delete and reinsert a row with the Import and Export utilities, for example, then its rowid may change. If you delete a row, then Oracle may reassign its rowid to a new row inserted later.
Although you can use the ROWID pseudocolumn in the SELECT and WHERE clause of a query, these pseudocolumn values are not actually stored in the database. You cannot insert, update, or delete a value of the ROWID pseudocolumn.
This statement selects the address of all rows that contain data for employees in department 20:
SELECT ROWID, last_name FROM employees WHERE department_id = 20;
O2SS0028: ROWID созданный столбец (Info)
В этой статье описывается причина, по которой помощник по миграции SQL Server (SSMA) для Oracle добавляет ROWID столбец в таблицу, если есть триггеры.
Общие сведения
В Oracle можно создать триггер, который будет выполняться FOR EACH ROW , а не для всего набора строк, изменяющихся. Триггеры SQL Server всегда выполняются для всего набора измененных строк. Если на уровне строк Oracle активирует доступ как к специальным переменным, :old так и :new к специальным переменным, SSMA требуется способ сопоставления строк из обоих наборов строк, чтобы определить, какое значение было для заданной строки до и после обновления. Чтобы эмулировать такие функции «для каждой строки», SSMA добавляет специальный ROWID столбец для уникальной идентификации каждой измененной строки и использует ее для установления связи между inserted наборами deleted строк.
пример
Рассмотрим следующий триггер Oracle, который выполняется для каждой строки, обновленной в TRIG_TEST таблице:
CREATE OR REPLACE TRIGGER TSCHM.TRIG_TEST_AU AFTER UPDATE OF DATA ON TSCHM.TRIG_TEST FOR EACH ROW BEGIN IF (:new.DATA = 'ABC') THEN INSERT INTO TSCHM.TRIG_TEST(DATA) VALUES ('-' || :old.DATA); END IF; END;
При попытке преобразовать этот триггер в SSMA в триггере SQL Server будет создан следующий T-SQL:
-
Запустите курсор над inserted набором строк, выберите ROWID и DATA столбцы в @new$0 и @new$DATA переменные:
DECLARE ForEachInsertedRowTriggerCursor CURSOR LOCAL FORWARD_ONLY READ_ONLY FOR SELECT ROWID, DATA FROM inserted OPEN ForEachInsertedRowTriggerCursor FETCH ForEachInsertedRowTriggerCursor INTO @new$0, @new$DATA
SELECT @old$0 = ROWID, @old$DATA = DATA FROM deleted WHERE ROWID = @new$0
IF (@new$DATA = 'ABC') INSERT SSMAADMIN.TRIG_TEST(DATA) VALUES (('-' + ISNULL(@old$DATA, '')))
Дополнительная информация
Это поведение управляется параметром проекта столбца ROWID, который можно найти в разделе — «Параметры — проекта» — общего преобразования — ROWID. Если для параметра задано значение No, но во время преобразования триггера SSMA определяет, что для него требуется ROWID столбец, будет создана ошибка преобразования O2SS0239 .
Связанные сообщения преобразования
- O2SS0239: столбец ROWID недоступен
- O2SS0267: столбец ROWID
- O2SS0404: невозможно преобразовать столбец ROWID
Обратная связь
Были ли сведения на этой странице полезными?
DB22SS0028: ROWID созданный столбец (Сведения)
В этой статье описывается причина, по которой помощник по миграции SQL Server (SSMA) для DB2 добавляет ROWID столбец в таблицу, если есть триггеры.
Общие сведения
В DB2 можно создать триггер, который будет выполняться FOR EACH ROW , а не для всего набора строк, изменяющихся. Триггеры SQL Server всегда выполняются для всего набора измененных строк. Если db2 уровня строк активирует доступ как к именам корреляций, OLD так и NEW к именам корреляций, SSMA требуется способ сопоставления строк из обоих наборов строк, чтобы определить, какое значение было для заданной строки до и после обновления. Чтобы эмулировать такие функции «для каждой строки», SSMA добавляет специальный ROWID столбец для уникальной идентификации каждой измененной строки и использует ее для установления связи между inserted наборами deleted строк.
пример
Рассмотрим следующий триггер DB2, который выполняется для каждой строки, обновленной в TRIG_TEST таблице:
CREATE OR REPLACE TRIGGER TSCHM.TRIG_TEST_AU AFTER UPDATE OF DATA ON TSCHM.TRIG_TEST REFERENCING OLD AS O NEW AS N FOR EACH ROW MODE DB2SQL BEGIN ATOMIC IF (N.DATA = 'ABC') THEN INSERT INTO TSCHM.TRIG_TEST(DATA) VALUES ('-' || O.DATA); END IF; END
При попытке преобразовать этот триггер в SSMA в триггере SQL Server будет создан следующий T-SQL:
-
Запустите курсор над inserted набором строк, выберите ROWID и DATA столбцы в @new$0 и @new$DATA переменные:
DECLARE ForEachInsertedRowTriggerCursor CURSOR LOCAL FORWARD_ONLY READ_ONLY FOR SELECT ROWID, DATA FROM inserted OPEN ForEachInsertedRowTriggerCursor FETCH ForEachInsertedRowTriggerCursor INTO @new$0, @new$DATA
SELECT @old$0 = ROWID, @old$DATA = DATA FROM deleted WHERE ROWID = @new$0
IF (@new$DATA = 'ABC') INSERT SSMAADMIN.TRIG_TEST(DATA) VALUES (('-' + ISNULL(@old$DATA, '')))
Дополнительные сведения
Это поведение управляется параметром проекта столбца ROWID, который можно найти в разделе — «Параметры — проекта» — общего преобразования — ROWID. Если параметр равен No, но во время преобразования триггера SSMA определяет, что для него требуется ROWID столбец, будет создана ошибка преобразования DB22SS0239 .
Связанные сообщения преобразования
- DB22SS0239: столбец ROWID недоступен
- DB22SS0267: столбец ROWID
- DB22SS0404: невозможно преобразовать столбец ROWID
Обратная связь
Были ли сведения на этой странице полезными?
Использование ROWID в запросах
Интересует как я могу использовать ROWID в запросах? Я нашел, что он применяется для быстрого удаление дубликатов записей в таблице:
DELETE FROM your_table WHERE rowid not in (SELECT MIN(rowid) FROM your_table GROUP BY column1, column2, column3);
Подскажите, как еще можно использовать это свойство? Или это больше не практическое, а теорическое свойство для понимания устройства БД?
Отслеживать
51.6k 200 200 золотых знаков 61 61 серебряный знак 242 242 бронзовых знака
задан 22 июл 2015 в 15:28
503 1 1 золотой знак 9 9 серебряных знаков 17 17 бронзовых знаков
По идее, использовать ROWID в голом виде это тыкать пальцем в БД, не зная, куда именно. Правильно использовать поля структуры таблицы для работы с БД, иначе можно поломать её целостность вплоть до необходимости поднимать из бэкапа и выплачивать отступные.
22 июл 2015 в 15:41
2 ответа 2
Сортировка: Сброс на вариант по умолчанию
ROWID — это физический адрес строки, поэтому доступ к строке по ее ROWID является наиболее быстрым способом.
ROWID уникален для каждой строки, поэтому его можно использовать в качестве суррогатного первичного ключа в различных запросах. Oracle гарантирует, что пока строка существует ее ROWID не изменится.
Но, постоянно полагаться на ROWID в качестве первичного ключа опасно.
Во-первых, строка может перемещаться (delete+insert) в результате различных действий (импорт\экспорт, перемещение строки в секционированной таблице при изменении значения ее колонок входящих в ключ секционирования, перемещение таблицы (alter table move), сжатии таблицы (alter table shrink) и т.п.).
Во-вторых, после удаления строки ее ROWID может быть переприсвоен какой-либо новой строке.
Отслеживать
ответ дан 23 июл 2015 в 8:29
3,807 1 1 золотой знак 18 18 серебряных знаков 27 27 бронзовых знаков
ROWID — это псевдоколонка. Она имеет одноимённый тип данных, их не следует путать.
В SQL запросе эта псевдоколонка возвращает адрес записи, служащий для её локализации.
Основные применения значений псевдоколонки ROWID :
- Обеспечивают самый быстрый путь доступа к записи.
- Дают информацию о месте хранении записи (см. описание пакета DBMS_ROWID)
- Они уникальны для каждой записи в таблице (см. пример в вопросе).
Для чего эти значения не следует использовать:
You should not use ROWID as the primary key of a table.
Значения ROWID актуальны только в текущий момент времени, но нет гарантии их неизменности. Их не следует использовать для первичных ключей, или хранить в БД для каких то других целей.
Важное замечание об уникальности значений псевдоколонки ROWID :
Usually, a rowid value uniquely identifies a row in the database. However, rows in different tables that are stored together in the same cluster can have the same rowid.
Они уникальны для таблицы, но не для БД в целом.
Практическое применение в SQL запросе относительно не частое.
В PL/SQL коде напротив — повседневно. Например, чтобы избежать повторного поиска записи в последующих статических запросах (быстрый доступ к уже найденной записи).
Так для явного указания в запросе:
create table t1 (id integer primary key, memo varchar2 (96)); insert into t1 select rownum, 'memo '||rownum from xmlTable ('1 to 9'); declare type ridarr is table of rowid; r ridarr; cur sys_refcursor; begin open cur for select rowid from t1 where id in (3,6); fetch cur bulk collect into r; forall ix in indices of r update t1 set memo = memo||'*' where rowid = r(ix); end;
А так неявно в предикате CURRENT OF , который определяет текущую запись по ROWID :
declare m t1.memo%type; cursor cur is select memo from t1 where id in (3,6) for update; begin open cur; loop fetch cur into m; exit when cur%notfound; update t1 set memo = m||'#' where current of cur; end loop; end;
