Пример использования с процедурой enable_at_time (так же есть вариант работы с scn)
-- готовим объекты
CREATE TABLE par(ID NUMBER PRIMARY KEY, txt VARCHAR2(10));
CREATE TABLE chi(par_id NUMBER REFERENCES par(ID) ON DELETE CASCADE, sm NUMBER);
INSERT INTO par VALUES (1, 'doc 1');
INSERT INTO par VALUES (2, 'doc 2');
INSERT INTO chi VALUES(1, 100);
INSERT INTO chi VALUES(2, 200);
-- Злой пользователей портит нашу жизнь
DELETE FROM par WHERE ID = 2;
UPDATE chi SET sm= -100 WHERE par_id = 1;
-- Тут мы фиксируем время, на которое будут выполняться запросы
-- В этом примере используется 1 минута назад, но
BEGIN
--dbms_flashback.disable;
DBMS_FLASHBACK.enable_at_time(SYSDATE - 1/24/60);
END;
/
-- Запросы без AS OF возвращают данные не испорченные пользователем
SELECT * FROM par;
SELECT * FROM chi;
Ну и ложка дегтя:
create table as select в этом режиме сделать невозможно
insert select в этом режиме сделать невозможно
Это делает эту фичу не сильно пригодной, для использования, хотя обходной маневр все таки есть -- пооткрывать курсоры
BEGIN
dbms_flashback.disable;
DBMS_FLASHBACK.enable_at_time(SYSDATE - 1/24/60);
END;
/
SELECT * FROM par;
SELECT * FROM chi;
DECLARE
CURSOR par_cur IS SELECT * FROM par;
par_row par_cur%ROWTYPE;
CURSOR chi_cur IS SELECT * FROM chi;
chi_row chi_cur%ROWTYPE;
BEGIN
OPEN par_cur;
OPEN chi_cur;
-- Отключаем фичу, что позволит нам вставлять данные в таблицу
dbms_flashback.disable;
-- таблицы для бекапов создаем в другой сессии
LOOP
FETCH par_cur INTO par_row;
EXIT WHEN par_cur%NOTFOUND;
INSERT INTO par_bkp VALUES par_row;
END LOOP;
LOOP
FETCH chi_cur INTO chi_row;
EXIT WHEN chi_cur%NOTFOUND;
INSERT INTO chi_bkp VALUES chi_row;
END LOOP;
COMMIT;
END;
/
SELECT * FROM par_bkp;
SELECT * FROM chi_bkp;
Но, бесспорно, ctas ... as of ... удобнее
Комментариев нет:
Отправить комментарий