web-dev-qa-db-ja.com

変更された値のみのトリガー

テーブルに3つのレコードがあるとします:orig_tab

---------------------------------------------
|  PK  |  Name  |  Address  |  Postal Code  |
---------------------------------------------
|   1  |  AA    |  Street1  |   11111       |
|   2  |  BB    |  Street2  |   22222       |
|   3  |  CC    |  Street3  |   33333       |
---------------------------------------------

これでデータが変更されました。

---------------------------------------------
|  PK  |  Name  |  Address  |  Postal Code  |
---------------------------------------------
|   1  |  AA    |  Street1  |   11111       |
|   2  |  BB    |  Street2  |   44444       |
|   3  |  CC    |  Dtreet7  |   33333       |
---------------------------------------------

クライアントが望んでいるのは、更新レコードと更新された列のみです(はい、意味がないことはわかっていますが、1970年代の古いシステムを使用しており、ロギングなどを実行したいと考えています)。したがって、レポートテーブルは次のようになります。

---------------------------------------------
|  PK  |  Name  |  Address  |  Postal Code  |
---------------------------------------------
|   2  |        |           |   44444       |
|   3  |        |  Dtreet7  |               |
---------------------------------------------

これは私が試したことです:

CREATE OR REPLACE TRIGGER vr_reporting_trigger
   AFTER UPDATE ON orig_tab
   FOR EACH ROW
BEGIN
IF inserting THEN
INSERT INTO rep_tab(pk, name, address, code)
  SELECT :new.pk, :new.name, :new.address, :new,code FROM DUAL
  WHERE NOT EXISTS (SELECT 1 FROM rep_tab WHERE pk = :new.pk);
UPDATE rep_tab t SET t.name = :new.name, t.address = :new.address, t.code = :new.code 
   WHERE t.pk = :new.pk;
ELSIF updating THEN
IF :new.pk <> :old.pk THEN
     UPDATE rep_tab t
        SET t.name = :new.name, t.address = :new.address, t.code =: new.code
      WHERE t.pk = :old.pk ;
  END IF;
  MERGE INTO rep_tab d
  USING DUAL ON (d.pk = :old.pk)
  WHEN MATCHED THEN
  UPDATE SET d.name = :new.name, d.address = :new.address, d.code =: new.code
  WHEN NOT MATCHED THEN
  INSERT (d.pk,d.name, d.address, d.code) VALUES (:new.pk,:new.name, new.address, new.code);
END IF;
END;

このソリューションで、私は得ます:

---------------------------------------------
|  PK  |  Name  |  Address  |  Postal Code  |
---------------------------------------------
|   2  |  BB    |  Street2  |   44444       |
|   3  |  CC    |  Dtreet7  |   33333       |
---------------------------------------------

ステートメントを更新するときに挿入句のどこかにあることは知っていますが、要件に従ってこの句を変更する方法がわかりません。なにか提案を?

前もって感謝します。

12
Jaanna

あなたにはこれが必要です:

UPDATEトリガーでは、UPDATING条件述部を使用して列名を指定し、指定された列が更新されているかどうかを判別できます。たとえば、トリガーが次のように定義されているとします。

CREATE OR REPLACE TRIGGER ...
... UPDATE OF Sal, Comm ON Emp_tab ...
BEGIN

... IF UPDATING ('SAL') THEN ... END IF;

END;

From Oracleドキュメント(9i)

11gR2ドキュメント

22
Florin Ghita

変更された値に対してのみトリガーします。

例として:

CREATE OR REPLACE TRIGGER trigger_department_update
  BEFORE UPDATE OF 
      department_id,
      cluster_id, 
      division_id, 
      macroregion_id, 
      address, 
      email
    ON cl_department
  FOR EACH ROW
BEGIN
  IF (
    :new.department_id != :old.department_id or
    :new.cluster_id != :old.cluster_id or
    :new.division_id != :old.division_id or
    :new.macroregion_id != :old.macroregion_id or
    :new.address != :old.address or
    :new.email != :old.email
  ) 
    THEN :new.update_date := CURRENT_TIMESTAMP; 
  END IF;
END;
2
Barh