результирующий набор все еще не содержит
новую строку и обновление, выполненные
Т1. Все дело в том, что Т2 является
транзакцией уровня serializable.
Ретроспективные запросы
Если выполненные изменения по ошибке зафиксированы и теперь нужно
увидеть строки в первоначальном виде, можно использовать ретроспективный
запрос (query flachback). Затем при желании можно воспользоваться
результатами этого ретроспективного запроса для ручного восстановления
ошибочно измененных строк до их первоначального значения.
Ретроспекции могут основываться на дате-времени или на номере изменений
системы (System Change Number - SCN). База данных использует
SCN для отслеживания изменений, внесенных в данные, и можно использовать
их для возврата к конкретному SCN в базе данных.
Предоставление полномочий для использования ретроспекций
В ретроспекциях используется пакет PL/SQL DBMS_FLASHBACK, для запуска
которого у пользователя должно быть полномочие EXECUTE. В следующем
примере производится подключение к базе данных от имени пользователя
sys и предоставление полномочия EXECUTE для пакета DBMS.FLASHBACK
пользователю store:
□ CONNECT sys/change_on_install AS sysdba
GRANT EXECUTE ON SYS.DBMS_FLASHBACK TO store;
Примечание Если при выполнении этих операторов возникнут ошибки, рекомендуем переговорить
с вашим АБД. Подробнее о полномочиях см. главу 9.0 пакетах PL/SQL см. главу 11.
Ретроспективные запросы по времени
В следующем примере показано подключение к базе данных как пользователь
store и отбор значений столбцов product.id, name и price для первых
пяти строк таблицы products:
282 Гпава 8
□ CONNECT store/ store_password
SELECT product_id, паше, price
FROM products
WHERE product_id <= 5;
PRODUCT_ID NAME PRICE
1 Modern Science 19.95
2 Chemistry 30
3 Supernova 25.99
4 Tank War 13.95
5 Z Files 49.99
Примечание Если вы видите другие цены для любого из этих товаров, выполните повторно
файл store_schema.sql. ____________ _________________________ __
В следующем примере для этих строк уменьшается цена товаров, фиксируются
изменения и снова выбираются эти строки, чтобы иметь возможность
увидеть новые цены:
□ UPDATE products
SET price = price * 0.75
WHERE product_id <= 5;
COMMIT;
SELECT product_id, name, price
FROM products
WHERE product_id <= 5;
PR0DUCT_ID NAME PRICE
1 Modern Science
2 Chemistry
3 Supernova
4 Tank War
5 Z Files
В следующем примере выполняется процедура DBMS_FLASHBACK. ENABLE,
AT_TIME(), которая позволяет выполнить ретроспекцию на конкретный
момент времени. Эта процедура принимает значение даты и времени, в
данном примере в процедуру передается значение SYSDATE - 10 / 1440, что
эквивалентно возвращению на 10 минут назад:
□ EXECUTE DBMS_FLASHBACK.ENABLE_AT_TIME(SYSDATE - 10 / 1440);
Примечание 24 ч * 60 мин/ч = 1440 мин. Следовательно, SYSDATE - 10/1440 эквивалентно
возвращению на 10 минут назад. ____ _____________________________
Если теперь выполнить какой угодно запрос, его результатом будут те
значения строк, которые они имели 10 минут назад. Если предположить,
что оператор UPDATE был выполнен менее 10 минут назад, то следующий
запрос покажет значения цен, которые были перед обновлением.
14.96
22.5
19.49
10.46
37.49
Изменение содержимого таблиц 283
□ SELECT produ ct_id, name, p r ic e
FROM products
WHERE p ro du ct_id <= 5;
PRODUCT_ID NAME PRICE
1 Modern Science 19.95
2 Chemistry 30
3 Supernova 25.99
4 Tank War 13.95
5 Z Files 49.99
Чтобы запретить выполнение ретроспекций, используется процедура
DBMS_FLASHBACK.DISABLE():
□ EXECUTE DBMS_FLASHBACK.DISABLE();
Предупреждение До того как еще раз активировать ретроспекцию, ее необходимо запретить.
Теперь при выполнении запросов снова можно получить строки в том
виде, в каком они существуют в данный момент:
□ SELECT prod u ct_id , name, p r ic e
FROM products
WHERE p rodu ct_id <= 5;
О 1— 1 NAME PRICE
1 Modern Science 14.96
2 Chemistry 22.5
3 Supernova 19.49
4 Tank War 10.46
5 Z Files 37.49
Ретроспективные запросы на базе системных номеров изменений
Ретроспекции на базе номеров изменений системы (SCN) могут быть более
точными, чем ретроспекции, основанные на времени, поскольку для
отслеживания изменений база данных использует SCN. Для получения текущего
значения SCN можно выполнить процедуру DBMS_FLASHBACK. GET_
SYSTEM_CHANGE_NUMBER:
□ VARIABLE cu rre n t_ scn NUMBER
EXECUTE : cu rre n t_ scn := DBMS_FLASHBACK.GET_SYSTEM_CHANGE_NUMBER();
PRINT cu rre n t_ scn
CURRENT_SCN
292111
В следующем примере в таблицу products добавляется строка, затем изменения
фиксируются, и выбирается новая строка:
28 4 Глава 8
□ INSERT INTO products (
product_id, product_type_id, name, description, price
) VALUES (
15, 1, ‘ Physics’ , ‘ Textbook on physics’ , 39.95