Запрос версий 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, которые вы делаете, на самом деле не актуальны, вы видите только две строки из-за того, когда вы зафиксировали данные.