2010년 10월 19일 화요일

Oracle_030. Triggers #1 - BEFORE_AFTER INSERT

Page 30. Triggers

  #1.
  이번에 원래 Import Data Pump 에 대해 사용했던 방법을 기술하려 했지만, 이번에 트리거를 작성할 일이 생겨서 Trigger 에 대하여 좋은 샘플이 있기에 무단으로 퍼옵니다. ' -';;
  트리거란 INSERT, UPDATE, DELETE 같은 DML 작업이 수행할때 DML 작업의 전후에 특정한 작업이 일어나게 설정해 놓는것을 말합니다.  예를들어 중요한 테이블에 DELETE를 수행하게 되면 DELETE 가 수행되기 전에 DELETE 될 행을 미리 트리거 테이블에 기록해 놓을 수 있습니다. 그래서 추후 복구할때 트리거 테이블을 참조하면 쉽게 복구가 가능하게 됩니다.

  #2-1.
  BEFORE INSERT Trigger.
  글자 그대로 Insert 작업 수행전에 일어나는 행위입니다. 다음은 Syntax 입니다.

    CREATE OR REPLACE TRIGGER TRIGGER_NAME
    BEFORE INSERT ON TABLE_NAME
       [ FOR EACH ROW ]
    DECLARE
        -- variable declarations
    BEGIN
        -- trigger code
    EXCEPTION
        WHEN ...
       -- exception handing
    END;

    TRIGGER_NAME 은 만들 트리거 이름입니다.
    다음은 해당 트리거의 제한사아이라고 합니다.
  • 뷰에는 Before Trigger 를 생성할 수 없습니다.
  • :NEW 값을 업데이트 할 수 있다고 하네요.
  • :OLD 값은 업데이트 할 수 없습니다.
  다음은 예제입니다. 다음과 같은 테이블을 생성했다고 가정합니다.

    CREATE TABLE ORDERS  (
        ORDER_ID           NUMBER(5),
        QUANTITY           NUMBER(5),
        COST_PER_ITEM NUMBER(6,2),
        TOTAL_COST      NUMBER(8,2),
        CREATE_DATE    DATE,
        CREATED_BY      VARCHAR2(10)
     );

  BEFORE INSERT 트리거는 다음과 같이 만들 수 있습니다.

    CREATE OR REPLACE TRIGGER ORDERS_BEFORE_INSERT
    BEFORE INSERT ON ORDERS
         FOR EACH ROW
    DECLARE
         v_username  varchar2(10);
    BEGIN
         -- 테이블에 인서트 작업을 수행하는 사용자 명을 찾습니다.
         SELECT username INTO v_username
         FROM DUAL;
         -- CREATE_DATE 컬럼을 현재 시스템 날짜로 업데이트 합니다.
         :new.create_date := sysdate;
         :new.created_by := v_username;
    END;

  #2-2
  AFTER INSERT Trigger
  인서트 작업 이후에 일어납니다. Syntax 는 다음과 같습니다.

    CREATE OR REPLACE TRIGGER TRIGGER_NAME
    AFTER INSERT ON TABLE_NAME
       [ FOR EACH ROW ]
    DECLARE
        -- variable declarations
    BEGIN
        -- trigger code
    EXCEPTION
        WHEN ...
       -- exception handing
    END;

  다음은 예제입니다.

    CREATE OR REPLACE TRIGGER ORDERS_BEFORE_INSERT
    BEFORE INSERT ON ORDERS
         FOR EACH ROW
    DECLARE
         v_username  varchar2(10);
    BEGIN
         -- 테이블에 인서트 작업을 수행하는 사용자 명을 찾습니다.
         SELECT username INTO v_username
         FROM DUAL;
         -- 추적테이블에 인서트 되는 행을 넣습니다..
         INSERT INTO orders_audit
         ( order_id, quantity, cost_per_item, total_cost, username )
         VALUES
         ( :new.order_id,
           :new.quantity,
           :new.cost_per_item,
           :new.total_cost,
           v_username );
    END;