1

2 つの日付列を持つテーブルで、次の状況がありStart_DTますEnd_DT

+----+------------+------------+
| ID |  Start_DT  |   End_DT   |
+----+------------+------------+
|  1 | 01-01-2012 | 02-01-2012 |
|  2 | 02-01-2012 | 05-02-2012 |
|  3 | 05-02-2012 | 07-02-2012 |
+----+------------+------------+

新しい行を挿入するときはいつでも、たとえば、次のタプルを挿入したい場合('06-02-2012', '10-02-2012')End_DT時系列の最後の (前の) 行の が、Start_DT挿入しようとしている行の で更新されます。時系列の重複

したがって、最終的に、新しい行を挿入すると、テーブルは次のようになります。

+----+------------+------------+
| ID |  Start_DT  |   End_DT   |
+----+------------+------------+
|  1 | 01-01-2012 | 02-01-2012 |
|  2 | 02-01-2012 | 05-02-2012 |
|  3 | 05-02-2012 | 06-02-2012 |
|  4 | 06-02-2012 | 10-02-2012 |
+----+------------+------------+

問題は、作成したトリガーでエラーが発生することです。これは、トリガーを作成した方法を理解していますが、目的を達成するためにそれを変更する方法がわかりません。

SQL Error: ORA-04091: table HISTORIC_TIME_TABLE is mutating, trigger/function may not see it

更新を行うには、前の行にロックSELECT FOR UDPATEをかけるために使用することが必須であると考えました。しかし、このトリガーを に変更すると、テーブルで同じロックを達成できるかどうかわかりません。AFTER

私のトリガーのコードは次のとおりです。

create or replace trigger trg_update_historic_time_table
before insert on HISTORIC_TIME_TABLE
for each row
declare

cursor upd_hist_tt_cur
is
    select start_dt, end_dt
    from HISTORIC_TIME_TABLE
    where (end_dt > sysdate)
    for update of end_dt;

begin

    for hist_cur_r in upd_hist_tt_cur loop
        if hist_cur_r.start_dt < :new.start_dt then
            update HISTORIC_TIME_TABLE
                set  end_dt = :new.start_dt
            where (start_dt = hist_cur_r.start_dt);
            commit;
        else
            :new.end_dt :=  hist_cur_r.start_dt;
        end if;
    end loop;

exception when no_data_found then null;
end;

BEFORE トリガーが同じテーブル内のデータを変更できないことをOracle のドキュメント ページでオンラインで見つけました。

Before triggers cannot have INSERT, UPDATE or DELETE statements as their action.
Before triggers cannot call procedures that modify SQL data as their action.

そのため、トリガーをタイプに変更することを考えていますが、そうすると、変数と変数AFTERにアクセスできなくなります。:new:old

どんな助けでも大歓迎です。

4

0 に答える 0