Как ни странно, но, практически у каждой БД есть пользователи :), а они постоянно пытаются сделать какие-нибудь пакости, которые не предусмотришь никакой программой.

Чтобы успешно отбиться от пользователей, утверждающих, что у тебя программа глючит, и от начальства, к которому пользователи тут же побегут жаловаться, нужно применять архивирование всех изменяемых и удаляемых строк критичных таблиц.

Предлагаемый вариант архивирования позволяет:

Основной принцип, заложеный в этом варианте, следующий:

Создаётся пользователь ARCHIV, в схеме которого (и от его имени!) размещаются архивные таблицы и процедуры для занесения архивируемых строк. В основной схеме размещаются триггеры на нужные таблицы, срабатывающие на изменение и удаление строк. В триггере находится вызов процедуры архивирования, которой передаются, в качестве параметров, все старые значения полей удаляемой или изменяемой строки.

Почему так сложно? Потому что конечный пользователь, в этом случае, не может увидеть и изменить заархивированные записи. Такой подход сработает в случае, если

Последовательность действий:

  1. Создаётся пользователь ARCHIV:

    CREATE USER ARCHIV IDENTIFIED BY ARCHIV;
    GRANT CREATE ANY INDEX TO "ARCHIV";
    GRANT CREATE ANY PROCEDURE TO "ARCHIV";
    GRANT CREATE SESSION TO "ARCHIV";
    GRANT CREATE TABLE TO "ARCHIV";

  2. В схеме основного пользователя создаются процедуры CR_ARC_TABLES и CR_TRIGGER.
  3. Запускается сначала один анонимный блок, который вызывает процедуру CR_ARC_TABLES для всех указанных в перечне таблиц (обязательно в верхнем регистре!) . DBMS output должен быть включён. Результат записать в файл arc_tables.sql.

    DECLARE 
    CURSOR c_tables IS 
    SELECT table_name FROM user_tables
    WHERE table_name IN ('TABLE1','TABLE2','TABLE3','TABLE4')
    ORDER BY 1;
    BEGIN 
    FOR c_tab IN c_tables LOOP
       CR_ARC_TABLES(c_tab.table_name);
    END loop; 
    end;
  4. Запускается второй анонимный блок, который вызывает процедуру CR_TRIGGER. Результат записать в файл arc_trigger.sql.

    DECLARE CURSOR c_tables IS SELECT table_name FROM user_tables WHERE table_name IN ('TABLE1','TABLE2','TABLE3','TABLE4') ORDER BY 1; BEGIN FOR c_tab IN c_tables LOOP CR_TRIGGER(c_tab.table_name); END loop; end;
  5. От пользователя ARCHIV запускается первый файл:
    SQLPlus archiv/archiv@Ваша БД @arc_tables.sql

    Создаются все архивные таблицы и процедуры.
  6. От основного пользователя запускается второй файл:
    SQLPlus ubc/passw@Ваша БД @arc_trigger.sql

    Создаются и запускаются все триггеры.

Всё, любуйтесь результатом.

В случае, если отслеживаемые таблицы изменяются очень часто в ходе работы в стандартном режиме, нужно подправить триггеры, ввести в них соответствующие условия срабатывания или указать только критичные поля таблицы для срабатывания триггера. Иногда приходится разделять триггер на 2 части - отдельно для update и delete.

Если воспользоваться ежедневным сбором статистики на таблицы, то легко определять в каких архивных таблицах появились новые записи за предидущий день.

Чуть позже, как только придумаю, выложу удобный вариант просмотра результатов архивирования.

Хостинг от uCoz