оракул и история создания - PullRequest
2 голосов
/ 09 августа 2010

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

 CREATE OR REPLACE TRIGGER mySchema.trg_projectHistory
 BEFORE UPDATE OR DELETE
 ON mySchema.projects REFERENCING NEW AS New OLD AS Old
 FOR EACH ROW
 declare tmpVersion number;
 BEGIN
  select myPackage.GETPROJECTVERSION( :OLD.project_ID ) into tmpVersion from dual;

  INSERT INTO mySchema.projectHistiry
    ( project_ID, ..., version )
  VALUES
    ( :OLD.project_ID,
    ...
     tmpVersion
     );

EXCEPTION
 WHEN OTHERS THEN
   -- Consider logging the error and then re-raise
   RAISE;
END ;
/

Я получил три триггера для каждой из моих таблиц (проектов, задач, клиентов).

Вот проблема: не все меняется одновременно. Например, кто-то может просто обновить стоимость определенных задач. В этом случае срабатывает только один триггер, и я получил одну вставку. Я хотел бы вставить одну запись в 3 таблицы истории одновременно, даже если ничего не изменилось в таблицах проектов и клиентов.

Кроме того, что если кто-то изменит дату окончания проекта, стоимость и скажет, что он выбирает другого клиента. Теперь у меня есть три спусковых крючка одновременно. Только в этом случае мне будет вставлена ​​одна запись в три таблицы истории. (который я хочу)

Если я изменю триггеры для вставки в 3 таблицы для первого примера, тогда у меня будет 9 вставок, когда произойдет второй пример.

Не совсем уверен, как справиться с этим. любая помощь?

Ответы [ 3 ]

2 голосов
/ 10 августа 2010

Для меня это звучит так, как будто вам нужен снимок уровня трех транзакций, созданный всякий раз, когда вы вносите изменения в любую из этих таблиц.

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

Упакованная процедура вставляет во все три таблицы истории соответствующий проект, клиента и задачи, для которых еще нет записи истории для этого ключа и транзакции (т. Е. Вам не нужны дубликаты). У вас есть пара вариантов, когда дело доходит до последнего. Вы можете использовать уникальное ограничение и либо BULK выделять и вставлять с FORALL / SAVE EXCEPTIONS, DML logging (EXCEPTIONS INTO) или INSERT ... SELECT ... WHERE NOT EXISTS ...

Вам необходимо отслеживать ваши транзакции. Я предполагаю, что это то, что вы делали с myPackage.GETPROJECTVERSION. Хитрость здесь в том, чтобы увеличивать версии только при наличии новой транзакции. Если, когда вы получаете новый номер версии, вы держите его в переменной уровня pacakge, вы можете легко определить, есть ли у вашей сессии номер версии или нет.

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

0 голосов
/ 10 августа 2010

Альтернативный ответ.Взгляните на Total Recall / Flashback Archive Вы можете установить срок хранения 10 лет и использовать простую AS OF TIMESTAMP для получения данных за любую конкретную метку времени.

Не уверен напроизводительность хотя.Может быть проще иметь ежедневное или еженедельное хранение, а затем отдельное запланированное задание, которое выбирает более старые версии с использованием синтаксиса VERSIONS BETWEEN и сохраняет их в таблице истории.

0 голосов
/ 09 августа 2010

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

Например. Таблица Project_hist будет содержать eff_date и exp_date, которые имеют дату начала и окончания для данного проекта. Таблица проекта просто будет иметь дату вступления в силу. (так как это активный проект).

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...