2026년 08월 24일 | DBMS Error 가이드
이 글에서 다루는 내용
ORA-04073 에러의 원인 분석, 해결 SQL, 예방 방법을 실무 관점에서 정리합니다.
ORA-04073 column list not valid for this trigger type 는?
ORA-04073 에러는 Oracle 데이터베이스에서 트리거를 생성할 때 특정 트리거 유형에 허용되지 않는 컬럼 목록(OF column_list)을 지정했을 때 발생합니다. 예를 들어, INSERT 또는 DELETE 트리거에 OF 컬럼명 절을 사용하는 경우가 대표적입니다. 이 에러는 DML 트리거 작성 시 트리거 유형별 문법 규칙을 정확히 이해하지 못한 상태에서 자주 발생하며, 트리거 생성 DDL 실행 시점에 즉각적으로 나타납니다.
주요 발생 원인
1. INSERT 또는 DELETE 트리거에 OF 컬럼 절 사용
Oracle의 DML 트리거에서 OF column_list 절은 오직 UPDATE 이벤트에만 사용할 수 있습니다. INSERT나 DELETE 이벤트는 특정 컬럼에 대한 변경을 구분할 필요가 없기 때문에 컬럼 목록 지정 자체가 문법적으로 허용되지 않습니다. 즉, BEFORE INSERT OF emp_name ON employees 와 같은 형태는 Oracle 파서가 문법 오류로 처리합니다.
2. 복합 이벤트(INSERT OR UPDATE OR DELETE) 트리거에서의 잘못된 OF 절 사용
트리거를 복합 이벤트로 선언할 때 INSERT OR UPDATE OR DELETE OF column_name 처럼 컬럼 목록을 지정하면 에러가 발생합니다. OF 절은 UPDATE 단독 또는 UPDATE를 포함한 이벤트 조합에서 UPDATE OF column_name 형태로만 기술해야 합니다. 잘못된 위치에 컬럼 목록을 붙이면 Oracle 엔진이 해당 트리거 유형에 컬럼 리스트가 유효하지 않다고 판단합니다.
3. DDL 트리거나 INSTEAD OF 트리거에 OF 컬럼 절 혼용
DDL 트리거(예: CREATE, DROP, ALTER 이벤트 기반 트리거)나 뷰(View) 대상의 INSTEAD OF 트리거를 작성할 때 실수로 OF column_name 절을 포함시키는 경우에도 이 에러가 발생합니다. DDL 트리거와 INSTEAD OF 트리거는 컬럼 수준 이벤트 필터링 기능 자체를 지원하지 않으므로, 해당 절을 사용하면 즉시 ORA-04073이 발생합니다.
해결 방법
원인 1 해결: INSERT/DELETE 트리거에서 OF 절 제거
잘못된 코드 (에러 발생)
-- ORA-04073 발생 예시
CREATE OR REPLACE TRIGGER trg_emp_insert
BEFORE INSERT OF salary ON employees
FOR EACH ROW
BEGIN
DBMS_OUTPUT.PUT_LINE('급여 값: ' || :NEW.salary);
END;
/
올바른 코드 (수정)
-- INSERT 트리거에서는 OF 절을 제거합니다
CREATE OR REPLACE TRIGGER trg_emp_insert
BEFORE INSERT ON employees
FOR EACH ROW
BEGIN
DBMS_OUTPUT.PUT_LINE('새로 입력된 급여 값: ' || :NEW.salary);
END;
/
INSERT 트리거는 모든 새 행 삽입에 대해 동작하므로 컬럼 필터가 불필요합니다. 트리거 바디 내에서 :NEW.column_name으로 원하는 컬럼 값을 직접 참조하면 됩니다.
원인 2 해결: UPDATE에만 OF 절 적용
잘못된 코드 (에러 발생)
-- ORA-04073 발생 예시 (복합 이벤트에 잘못된 OF 절)
CREATE OR REPLACE TRIGGER trg_emp_dml
BEFORE INSERT OR UPDATE OR DELETE OF salary ON employees
FOR EACH ROW
BEGIN
IF INSERTING THEN
DBMS_OUTPUT.PUT_LINE('INSERT 발생');
ELSIF UPDATING THEN
DBMS_OUTPUT.PUT_LINE('UPDATE 발생');
ELSIF DELETING THEN
DBMS_OUTPUT.PUT_LINE('DELETE 발생');
END IF;
END;
/
올바른 코드 (수정)
-- UPDATE OF 절을 UPDATE 이벤트에만 적용하는 올바른 방법
-- 방법 1: UPDATE만 OF 절과 함께 사용
CREATE OR REPLACE TRIGGER trg_emp_salary_update
BEFORE UPDATE OF salary ON employees
FOR EACH ROW
BEGIN
DBMS_OUTPUT.PUT_LINE('급여 변경: ' || :OLD.salary || ' → ' || :NEW.salary);
END;
/
-- 방법 2: 복합 이벤트가 필요한 경우 OF 절 없이 선언 후 바디에서 분기
CREATE OR REPLACE TRIGGER trg_emp_dml
BEFORE INSERT OR UPDATE OR DELETE ON employees
FOR EACH ROW
BEGIN
IF INSERTING THEN
DBMS_OUTPUT.PUT_LINE('INSERT 발생 - 사원: ' || :NEW.emp_name);
ELSIF UPDATING('SALARY') THEN
-- UPDATING('컬럼명') 함수를 활용하여 특정 컬럼 변경 여부 확인
DBMS_OUTPUT.PUT_LINE('급여 UPDATE 발생: ' || :OLD.salary || ' → ' || :NEW.salary);
ELSIF UPDATING THEN
DBMS_OUTPUT.PUT_LINE('기타 컬럼 UPDATE 발생');
ELSIF DELETING THEN
DBMS_OUTPUT.PUT_LINE('DELETE 발생 - 사원: ' || :OLD.emp_name);
END IF;
END;
/
복합 이벤트 트리거에서 특정 컬럼의 변경 여부를 체크하고 싶다면, OF 절 대신 트리거 바디 내에서 UPDATING('컬럼명') 조건 함수를 활용하는 것이 가장 권장되는 방식입니다.
원인 3 해결: INSTEAD OF 트리거에서 OF 절 제거
잘못된 코드 (에러 발생)
-- INSTEAD OF 트리거에 OF 절 사용 시 ORA-04073 발생
CREATE OR REPLACE TRIGGER trg_emp_view_upd
INSTEAD OF UPDATE OF salary ON emp_view
FOR EACH ROW
BEGIN
UPDATE employees
SET salary = :NEW.salary
WHERE employee_id = :OLD.employee_id;
END;
/
올바른 코드 (수정)
-- INSTEAD OF 트리거는 OF 절 없이 선언, 바디에서 컬럼 조건 처리
CREATE OR REPLACE TRIGGER trg_emp_view_upd
INSTEAD OF UPDATE ON emp_view
FOR EACH ROW
BEGIN
-- 특정 컬럼 변경 여부는 UPDATING() 함수로 처리
IF UPDATING('SALARY') THEN
UPDATE employees
SET salary = :NEW.salary
WHERE employee_id = :OLD.employee_id;
END IF;
IF UPDATING('EMP_NAME') THEN
UPDATE employees
SET emp_name = :NEW.emp_name
WHERE employee_id = :OLD.employee_id;
END IF;
END;
/
현재 잘못 생성된 트리거 확인 쿼리
-- 현재 데이터베이스의 무효화된 트리거 목록 조회
SELECT owner,
trigger_name,
trigger_type,
triggering_event,
table_name,
status
FROM dba_triggers
WHERE status = 'DISABLED'
OR status = 'INVALID'
ORDER BY owner, trigger_name;
-- 특정 테이블의 트리거 상세 정보 확인
SELECT trigger_name,
trigger_type,
triggering_event,
column_name, -- UPDATE OF 절에 지정된 컬럼명
status
FROM dba_triggers
WHERE table_name = 'EMPLOYEES'
ORDER BY trigger_name;
예방 방법
1. 트리거 생성 전 문법 템플릿 표준화 및 코드 리뷰 적용
팀 내에서 트리거 작성 시 사용할 표준 템플릿을 미리 정의하고, 특히 OF column_list 절은 UPDATE 이벤트에만 사용 가능하다는 규칙을 템플릿 주석에 명시해 두는 것이 좋습니다. 신규 트리거 DDL을 운영 환경에 배포하기 전 반드시 개발/테스트 환경에서 컴파일 검증을 거치고, 동료 DBA 또는 시니어 개발자의 코드 리뷰를 의무화하면 이 유형의 문법 오류를 사전에 차단할 수 있습니다.
2. UPDATING() 조건 함수를 활용한 컬럼 수준 제어 습관화
OF column_list 절에만 의존하지 않고, 트리거 바디 내에서 UPDATING('컬럼명'), INSERTING, DELETING 조건 함수를 적극 활용하는 코딩 습관을 정착시키는 것이 좋습니다. 이 방식은 복합 이벤트 트리거에서도 유연하게 동작하며, OF 절의 잘못된 사용으로 인한 ORA-04073 에러를 원천적으로 예방할 수 있을 뿐 아니라 트리거 로직의 가독성과 유지보수성도 향상시킵니다.
관련 에러
- ORA-04071: 트리거 이벤트 지정이 누락되었거나 잘못된 경우 (
missing BEFORE, AFTER or INSTEAD OF keyword) - ORA-04072: 잘못된 트리거 유형이 지정된 경우 (
invalid trigger type) - ORA-04074: 잘못된 REFERENCING 이름을 지정한 경우 (
invalid REFERENCING name) - ORA-00942: 트리거 대상 테이블 또는 뷰가 존재하지 않을 때 발생 (
table or view does not exist) - ORA-04076:
NEW또는OLD참조가 잘못된 트리거 유형에서 사용된 경우 (invalid NEW or OLD specification)
이러한 에러들은 모두 트리거 생성(DDL) 단계에서 발생하며, Oracle 공식 문서의 PL/SQL Language Reference와 SQL Language Reference의 CREATE TRIGGER 구문 섹션을 함께 참고하면 정확한 문법을 빠르게 확인할 수 있습니다.
주요 DBMS error code를 정리하는 시리즈입니다.
블로그 홈에서 다른 에러도 확인하세요.
본 포스트는 AI가 생성한 기술 가이드입니다. 운영 환경 적용 전 충분한 검토를 권장합니다.