[Oracle] 트리거를 이용하여 로그 테이블 기록하기. Trigger Log Table

오라클 로그

오라클 데이터베이스에서 유지보수를 하다보면, 데이터의 수정과 삭제가 어떻게 이루어지고 있는지 즉시 확인하고 싶은 경우가 있습니다.

오늘은 트리거를 이용하여 로그 테이블에 데이터를 기록하는 방법에 대해 알아보도록 하겠습니다~ 로그 테이블 스크립트와 트리거 스크립트를 작성해 보도록 하겠습니다.

트리거 로그 테이블

오라클 로그 테이블을 만들어 봅시다. 사용자가 로그를 볼 수 있도록 추가해 보는 것이 목표랍니다~

기록을 남길 테이블은 EMP 테이블이며, 로그 테이블 구성은 본래의 테이블 컬럼과 함께, 터미널, 아이피, 로그데이트, 타입을 남기도록 하겠습니다.

--기존 테이블 컬럼
  EMPNO     NUMBER(4),
  ENAME     VARCHAR2(10 BYTE),
  JOB       VARCHAR2(9 BYTE),
  MGR       NUMBER(4),
  HIREDATE  DATE,
  SAL       NUMBER(7,2),
  COMM      NUMBER(7,2),
  DEPTNO    NUMBER(2)
--로그 관련 컬럼
  LOG_TERMINAL  VARCHAR2 (100 BYTE),
  LOG_IPADDRESS VARCHAR2 (100 BYTE),
  LOG_DATE      DATE DEFAULT SYSDATE,
  LOG_TYPE      VARCHAR2 (1 BYTE)

그리하여 로그 테이블은 트리거 대상 테이블보다 컬럼 개수가 많게 설정합니다.

--로그 테이블 전체 컬럼
  EMPNO          NUMBER(4),
  ENAME          VARCHAR2(10 BYTE),
  JOB            VARCHAR2(9 BYTE),
  MGR            NUMBER(4),
  HIREDATE       DATE,
  SAL            NUMBER(7,2),
  COMM           NUMBER(7,2),
  DEPTNO         NUMBER(2),
  LOG_TERMINAL   VARCHAR2(100 BYTE),
  LOG_IPADDRESS  VARCHAR2(100 BYTE),
  LOG_DATE       DATE DEFAULT SYSDATE,
  LOG_TYPE       VARCHAR2(1 BYTE)

로그 테이블

CREATE TABLE user_name.log_table_name
(
  EMPNO     NUMBER(4),
  ENAME     VARCHAR2(10 BYTE),
  JOB       VARCHAR2(9 BYTE),
  MGR       NUMBER(4),
  HIREDATE  DATE,
  SAL       NUMBER(7,2),
  COMM      NUMBER(7,2),
  DEPTNO    NUMBER(2),
  LOG_TERMINAL  VARCHAR2 (100 BYTE),
  LOG_IPADDRESS VARCHAR2 (100 BYTE),
  LOG_DATE      DATE DEFAULT SYSDATE,
  LOG_TYPE      VARCHAR2 (1 BYTE)
)
TABLESPACE tablespace_name
PCTUSED 0
PCTFREE 10
INITRANS 1
MAXTRANS 255
STORAGE (INITIAL 64 M
         NEXT 1 M
         MINEXTENTS 1
         MAXEXTENTS UNLIMITED
         PCTINCREASE 0
         BUFFER_POOL DEFAULT)
LOGGING
NOCOMPRESS
NOCACHE
NOPARALLEL
MONITORING;

COMMENT ON TABLE user_name.log_table_name IS '로그 테이블';
COMMENT ON COLUMN user_name.log_table_name.LOG_TERMINAL IS '로그 단말';
COMMENT ON COLUMN user_name.log_table_name.LOG_IPADDRESS IS '로그 주소';
COMMENT ON COLUMN user_name.log_table_name.LOG_DATE IS '로그 일시';
COMMENT ON COLUMN user_name.log_table_name.LOG_TYPE IS '로그 유형';

로그 트리거

CREATE OR REPLACE TRIGGER tr_log_table_name
   AFTER DELETE OR UPDATE
   ON user_name.emp
   REFERENCING NEW AS NEW OLD AS OLD
   FOR EACH ROW
DECLARE
   L_V_IPADDRESS   VARCHAR2 (100);
   L_V_TERMINAL    VARCHAR2 (100);
   L_V_LOGTYPE     VARCHAR2 (1);
BEGIN
   SELECT SYS_CONTEXT ('USERENV', 'IP_ADDRESS'),
          SYS_CONTEXT ('USERENV', 'TERMINAL')
     INTO L_V_IPADDRESS, L_V_TERMINAL
     FROM DUAL;

   IF UPDATING
   THEN
      L_V_LOGTYPE := 'U';
   ELSE
      L_V_LOGTYPE := 'D';
   END IF;

    Insert into user_name.log_table_name
       (EMPNO, 
        ENAME, JOB, MGR, HIREDATE, SAL, 
        COMM, DEPTNO,
        LOG_TERMINAL, LOG_IPADDRESS, LOG_DATE, LOG_TYPE)
     Values
       (:OLD.EMPNO, 
        :OLD.ENAME, :OLD.JOB, :OLD.MGR, :OLD.HIREDATE, :OLD.SAL, 
        :OLD.COMM, :OLD.DEPTNO,
        L_V_TERMINAL, L_V_IPADDRESS, SYSDATE, L_V_LOGTYPE);

EXCEPTION
   WHEN OTHERS
   THEN
      NULL;
END;
/

트리거 예제

수정, 삭제 이후 OLD 값을 기록하도록 합니다. 변경 이후 값은 본래 테이블에 갱신되기 때문에 NEW 값을 별도로 기록할 필요는 없을 것입니다.

다음과 같이 로그 트리거 스크립트를 확인하기 위한 테스트를 진행하겠습니다. 트리거 확인 차원에서 현재 데이터의 일부 값을 변경해 봅시다. 그리고 로그 테이블을 조회해 봅시다.

UPDATE EMP
   SET EMPNO = EMPNO
 WHERE EMPNO = 7839;

1 row updated.

로그 테이블에 수정 내역을 확인할 수 있답니다. 수정 이전 내역을 로그 테이블에서 다음과 같이 확인할 수 있습니다.

SELECT * FROM LOG_TABLE_NAME;

     EMPNO ENAME                JOB                       MGR HIREDATE        SAL       COMM     DEPTNO LOG_TERMINAL    LOG_IPADDRESS
 LOG_DATE LO
----------
      7839 KING                 PRESIDENT                     96/11/17       5000                    10 TERMINAL
 99/12/31 U

댓글