Oracle ORA-04070 오류 원인과 해결 방법 완벽 가이드

ORA-04070
2026년 08월 23일 | DBMS Error 가이드

이 글에서 다루는 내용

ORA-04070 에러의 원인 분석, 해결 SQL, 예방 방법을 실무 관점에서 정리합니다.

ORA-04070 invalid trigger name 는?

ORA-04070 에러는 Oracle 데이터베이스에서 트리거(Trigger)를 생성하거나 수정, 삭제할 때 트리거 이름이 유효하지 않을 경우 발생하는 에러입니다. 트리거 이름이 Oracle의 명명 규칙(Naming Convention)을 위반하거나, 예약어(Reserved Word)를 사용하거나, 존재하지 않는 트리거를 참조할 때 주로 발생합니다. 이 에러는 DDL 작업 시 자주 마주치게 되며, 특히 대규모 시스템 마이그레이션이나 애플리케이션 배포 과정에서 빈번하게 나타납니다.


주요 발생 원인

1. 트리거 이름이 Oracle 명명 규칙을 위반한 경우

Oracle에서 트리거 이름은 반드시 영문자(또는 일부 특수문자)로 시작해야 하며, 최대 30자(Oracle 12.2 이전) 또는 128자(Oracle 12.2 이후)를 초과할 수 없습니다. 숫자로 시작하거나, 하이픈(-), 공백, 특수문자 등을 포함한 이름을 사용하면 이 에러가 발생합니다. 실무에서는 타 시스템에서 이관된 스크립트에 이러한 규칙 위반이 포함되어 있는 경우가 많습니다.

2. Oracle 예약어(Reserved Word)를 트리거 이름으로 사용한 경우

SELECT, TABLE, INDEX, TRIGGER, WHERE 등 Oracle이 내부적으로 사용하는 예약어를 트리거 이름으로 지정하면 파서(Parser)가 이를 올바르게 해석하지 못해 에러가 발생합니다. 개발자가 의미 있는 이름을 부여하려다 우연히 예약어와 겹치는 경우가 많으며, 이는 운영 환경 배포 직전에 발견되는 경우가 많아 주의가 필요합니다. 예약어 목록은 Oracle 공식 문서(V$RESERVED_WORDS 뷰)를 통해 반드시 확인해야 합니다.

3. 존재하지 않는 트리거를 ALTER 또는 DROP으로 참조한 경우

ALTER TRIGGER 또는 DROP TRIGGER 구문을 실행할 때 해당 이름의 트리거가 데이터베이스에 존재하지 않으면 ORA-04070 에러가 발생할 수 있습니다. 이는 스키마(Schema) 혼동이나 오탈자(Typo)로 인해 잘못된 트리거 이름을 참조하는 경우에 빈번하게 발생합니다. 특히 여러 환경(개발, 스테이징, 운영)에서 동일한 스크립트를 사용할 때 환경별 객체 존재 여부를 먼저 확인하지 않으면 이 문제가 자주 발생합니다.


해결 방법

원인 1: 명명 규칙 위반 해결

잘못된 트리거 이름을 올바른 명명 규칙에 맞게 수정합니다. 아래는 잘못된 예와 올바른 예입니다.

-- ❌ 잘못된 예: 숫자로 시작하는 트리거 이름
CREATE OR REPLACE TRIGGER 1st_trg_employees
BEFORE INSERT ON employees
FOR EACH ROW
BEGIN
  :NEW.created_date := SYSDATE;
END;
/

-- ✅ 올바른 예: 영문자로 시작하는 트리거 이름
CREATE OR REPLACE TRIGGER trg_employees_before_insert
BEFORE INSERT ON employees
FOR EACH ROW
BEGIN
  :NEW.created_date := SYSDATE;
END;
/
-- ❌ 잘못된 예: 특수문자 및 공백 포함
CREATE OR REPLACE TRIGGER "emp-insert trigger"
BEFORE INSERT ON employees
FOR EACH ROW
BEGIN
  NULL;
END;
/

-- ✅ 올바른 예: 언더스코어(_)만 사용
CREATE OR REPLACE TRIGGER trg_emp_insert
BEFORE INSERT ON employees
FOR EACH ROW
BEGIN
  NULL;
END;
/

원인 2: 예약어 사용 해결

예약어 여부를 먼저 확인한 후 트리거 이름을 변경합니다.

-- 예약어 확인 쿼리
SELECT keyword, reserved
FROM v$reserved_words
WHERE keyword = 'TRIGGER'  -- 확인하고 싶은 단어로 교체
ORDER BY keyword;

-- ❌ 잘못된 예: 예약어 'TRIGGER'를 이름으로 사용
CREATE OR REPLACE TRIGGER TRIGGER
BEFORE DELETE ON employees
FOR EACH ROW
BEGIN
  NULL;
END;
/

-- ✅ 올바른 예: 예약어를 피한 이름 사용
CREATE OR REPLACE TRIGGER trg_emp_delete_audit
BEFORE DELETE ON employees
FOR EACH ROW
BEGIN
  INSERT INTO emp_audit_log (emp_id, action, action_date)
  VALUES (:OLD.employee_id, 'DELETE', SYSDATE);
END;
/

원인 3: 존재하지 않는 트리거 참조 해결

작업 전 트리거 존재 여부를 반드시 확인하고, 조건부 처리를 활용합니다.

-- 현재 스키마의 트리거 목록 확인
SELECT trigger_name, table_name, status, trigger_type
FROM user_triggers
WHERE trigger_name LIKE 'TRG_%'
ORDER BY trigger_name;

-- 특정 트리거 존재 여부 확인
SELECT COUNT(*) AS cnt
FROM user_triggers
WHERE trigger_name = 'TRG_EMP_INSERT';  -- 대문자로 확인

-- 안전한 DROP 처리 (존재할 때만 삭제)
DECLARE
  v_count NUMBER;
BEGIN
  SELECT COUNT(*)
  INTO v_count
  FROM user_triggers
  WHERE trigger_name = 'TRG_EMP_INSERT';

  IF v_count > 0 THEN
    EXECUTE IMMEDIATE 'DROP TRIGGER trg_emp_insert';
    DBMS_OUTPUT.PUT_LINE('트리거가 성공적으로 삭제되었습니다.');
  ELSE
    DBMS_OUTPUT.PUT_LINE('해당 트리거가 존재하지 않습니다.');
  END IF;
END;
/

-- ALTER TRIGGER 전 상태 확인
SELECT trigger_name, status
FROM user_triggers
WHERE trigger_name = 'TRG_EMP_INSERT';

-- 트리거 활성화/비활성화
ALTER TRIGGER trg_emp_insert ENABLE;
ALTER TRIGGER trg_emp_insert DISABLE;

예방 방법

1. 표준화된 트리거 네이밍 컨벤션(Naming Convention) 수립 및 준수

팀 또는 조직 내에서 트리거 이름에 대한 명명 규칙을 문서화하고 모든 개발자가 준수하도록 합니다. 예를 들어 TRG_[테이블명]_[이벤트] 형식(예: TRG_EMPLOYEES_BEFORE_INSERT)을 표준으로 지정하면 가독성과 일관성을 동시에 확보할 수 있습니다. CI/CD 파이프라인에 DDL 스크립트 검증 단계를 추가하여 배포 전 명명 규칙 위반을 자동으로 감지하는 것을 권장합니다.

2. 배포 전 객체 존재 여부 검증 스크립트 활용

운영 환경에 배포하기 전 반드시 대상 객체(트리거)의 존재 여부와 상태를 확인하는 검증 스크립트를 실행해야 합니다. 아래와 같이 사전 점검 쿼리를 표준 배포 절차에 포함시키는 것이 좋습니다.

-- 배포 전 트리거 상태 전체 점검 쿼리
SELECT trigger_name,
       table_name,
       trigger_type,
       triggering_event,
       status
FROM user_triggers
ORDER BY table_name, trigger_name;

관련 에러

  • ORA-04071: missing BEFORE, AFTER or INSTEAD OF keyword — 트리거 생성 시 필수 키워드 누락
  • ORA-04072: invalid trigger type — 지원하지 않는 트리거 타입 지정
  • ORA-04080: trigger name does not exist — 존재하지 않는 트리거를 참조할 때 발생하며 ORA-04070과 혼동하기 쉬움
  • ORA-00900: invalid SQL statement — 트리거 본문의 SQL 구문 오류 시 발생
  • ORA-04098: trigger is invalid and failed re-validation — 트리거가 컴파일 오류로 인해 INVALID 상태일 때 해당 트리거가 실행되려 할 때 발생

DBMS 에러 코드 시리즈

주요 DBMS error code를 정리하는 시리즈입니다.
블로그 홈에서 다른 에러도 확인하세요.

본 포스트는 AI가 생성한 기술 가이드입니다. 운영 환경 적용 전 충분한 검토를 권장합니다.

댓글 남기기