Запрос версий Flashback

select оператор возвращает две строки

id || описание
1 ДВА
2 ДВА 

Я ожидаю три ряда

id || описание
1 ОДИН
1 ДВА
2 ДВА 
согласно заявлению по ссылке, которая гласит It returns all the committed occurrences of the rows for a query of an object, while NOT displaying the UNCOMMITTED row versions. Код выглядит следующим образом:


CREATE TABLE digits
(id NUMBER(2),
description VARCHAR2(15));
INSERT INTO digits VALUES (1,'ONE');
UPDATE digits SET description ='TWO' WHERE id=1;
INSERT INTO digits VALUES (2,'TWO');
COMMIT;
DELETE FROM digits;
SELECT id,description FROM digits
VERSIONS BETWEEN TIMESTAMP MINVALUE AND MAXVALUE;

Единственная причина, о которой я мог подумать, это то, что если timestamp minvalue и maxvalue принимает значение метки времени DML, а не DDL..... пожалуйста, пролите немного света на это!

1 ответ

Решение

Строка, которую вы считаете отсутствующей, будет исходить из этого:

INSERT INTO digits VALUES (1,'ONE');

... но данные никогда не фиксируются в этом состоянии, потому что это:

UPDATE digits SET description ='TWO' WHERE id=1;

... произошло до вашего COMMIT, Так что это соответствует заявлению, которое вы цитировали, 1, ONE не является совершенным вхождением строки. Никогда не было момента, когда другой сеанс мог увидеть эти значения.

Если вы посмотрите на псевдостолбцы данных версии, то увидите, что обе строки отображаются как вставки со своими текущими данными:

CREATE TABLE digits (id NUMBER(2), description VARCHAR2(15));
EXEC dbms_lock.sleep(10);

INSERT INTO digits VALUES (1,'ONE');
UPDATE digits SET description ='TWO' WHERE id=1;
INSERT INTO digits VALUES (2,'TWO');
COMMIT;

SELECT id, description, versions_xid, versions_operation
FROM digits
VERSIONS BETWEEN TIMESTAMP MINVALUE AND MAXVALUE;

        ID DESCRIPTION     VERSIONS_XID     V
---------- --------------- ---------------- -
         2 TWO             08001B005C0D0100 I
         1 TWO             08001B005C0D0100 I

Если вы совершаете между первым insert а также update Вы можете увидеть три строки и как они были изменены:

CREATE TABLE digits (id NUMBER(2), description VARCHAR2(15));
EXEC dbms_lock.sleep(10);

INSERT INTO digits VALUES (1,'ONE');
COMMIT;
EXEC dbms_lock.sleep(10);

UPDATE digits SET description ='TWO' WHERE id=1;
INSERT INTO digits VALUES (2,'TWO');
COMMIT;

SELECT id, description, versions_xid, versions_operation
FROM digits
VERSIONS BETWEEN TIMESTAMP MINVALUE AND MAXVALUE;

        ID DESCRIPTION     VERSIONS_XID     V
---------- --------------- ---------------- -
         2 TWO             060018007C0C0100 I
         1 TWO             060018007C0C0100 U
         1 ONE             05000B00450C0100 I

Я не совсем уверен, почему SLEEP вызовы необходимы, но без них это не совсем работает (псевдоколонки пустые и отображаются только текущие данные). Я не думаю, что когда-либо видел хорошее объяснение этого, но вряд ли это будет проблемой в реальном случае.


Из документации:

Уточнить BETWEEN TIMESTAMP ... чтобы получить версии строки, которая существовала между двумя временными метками. Оба выражения должны принимать значение метки времени и не могут принимать значение NULL. MINVALUE а также MAXVALUE разрешить метку времени самых старых и самых последних доступных данных соответственно.

Обычно MINVALUE будет ограничено отменой сохранения; поскольку это новая таблица, она вернется к той точке, в которой была создана таблица, что меньше, чем удержание отмены. Вы не можете выйти за пределы этого, потому что это не имеет никакого смысла: если вы попытаетесь использовать явное значение метки времени до времени создания таблицы, это скажет вам, что структура таблицы изменилась. Различия DML/DDL, которые вы делаете, на самом деле не актуальны, вы видите только две строки из-за того, когда вы зафиксировали данные.

Другие вопросы по тегам