2026년 08월 25일 | DBMS Error 가이드
이 글에서 다루는 내용
ORA-04080 에러의 원인 분석, 해결 SQL, 예방 방법을 실무 관점에서 정리합니다.
ORA-04080 trigger does not exist 는?
ORA-04080 에러는 Oracle 데이터베이스에서 존재하지 않는 트리거(Trigger)를 삭제(DROP), 활성화(ENABLE), 비활성화(DISABLE) 또는 컴파일(ALTER … COMPILE)하려고 할 때 발생하는 에러입니다. 즉, 데이터베이스 딕셔너리에 등록되지 않은 트리거 이름을 참조했을 때 Oracle이 해당 객체를 찾을 수 없다는 사실을 알려주는 메시지입니다. 이 에러는 주로 트리거 이름 오타, 스키마 불일치, 또는 이미 삭제된 트리거에 대한 작업 시도 등 다양한 원인으로 실무에서 빈번하게 발생합니다.
주요 발생 원인
1. 트리거 이름 오타 또는 대소문자 불일치
Oracle은 기본적으로 객체 이름을 대문자로 저장합니다. 트리거를 생성할 때 큰따옴표(“)로 감싸 소문자 이름을 사용했거나, DROP/ALTER 명령 시 이름을 잘못 입력한 경우 ORA-04080이 발생합니다. 예를 들어 trg_order_insert라는 이름으로 트리거를 생성했지만 TRG_ORDER_INSERT와 다른 철자를 사용했다면 에러가 발생합니다.
2. 잘못된 스키마(Schema) 참조
현재 접속한 사용자의 스키마와 트리거가 실제로 속해 있는 스키마가 다를 경우 이 에러가 발생합니다. 예를 들어 SCOTT 스키마에서 작업하면서 HR 스키마에 있는 트리거를 스키마 명시 없이 조작하려 하면 Oracle은 해당 트리거를 찾지 못합니다. DBA 권한이 있어도 스키마 이름을 명시하지 않으면 반드시 현재 세션의 스키마에서 먼저 탐색합니다.
3. 이미 삭제되었거나 생성 실패한 트리거 참조
트리거가 이전에 이미 DROP된 상태이거나, CREATE OR REPLACE 과정에서 컴파일 에러로 인해 트리거가 INVALID 상태가 아닌 아예 생성되지 않은 경우에도 이 에러가 발생합니다. 자동화 스크립트나 배포 파이프라인에서 동일한 DROP 명령이 두 번 실행되는 경우가 특히 많으며, 이는 개발 환경에서 자주 목격되는 패턴입니다.
해결 방법
원인 1 해결: 트리거 존재 여부 먼저 확인
작업 전 반드시 데이터 딕셔너리를 조회하여 트리거 이름과 소유자를 정확히 확인하세요.
-- 현재 사용자 소유의 트리거 목록 조회
SELECT TRIGGER_NAME, STATUS, TRIGGER_TYPE, TRIGGERING_EVENT, TABLE_NAME
FROM USER_TRIGGERS
WHERE TRIGGER_NAME = 'TRG_ORDER_INSERT';
-- DBA 권한으로 전체 스키마 조회
SELECT OWNER, TRIGGER_NAME, STATUS, TABLE_NAME
FROM DBA_TRIGGERS
WHERE TRIGGER_NAME LIKE '%ORDER%';
-- 대소문자 구분 없이 검색
SELECT OWNER, TRIGGER_NAME
FROM DBA_TRIGGERS
WHERE UPPER(TRIGGER_NAME) = UPPER('trg_order_insert');
원인 2 해결: 스키마를 명시하여 트리거 조작
트리거가 다른 스키마에 있을 경우 반드시 스키마명.트리거명 형식으로 명령을 실행하세요.
-- 잘못된 방법 (스키마 미명시 - ORA-04080 발생 가능)
ALTER TRIGGER TRG_SALARY_UPDATE DISABLE;
-- 올바른 방법 (스키마 명시)
ALTER TRIGGER HR.TRG_SALARY_UPDATE DISABLE;
-- 트리거 활성화
ALTER TRIGGER HR.TRG_SALARY_UPDATE ENABLE;
-- 트리거 재컴파일
ALTER TRIGGER HR.TRG_SALARY_UPDATE COMPILE;
-- DBA 권한으로 특정 테이블의 모든 트리거 비활성화
ALTER TABLE HR.EMPLOYEES DISABLE ALL TRIGGERS;
원인 3 해결: 안전한 DROP 스크립트 작성
이미 삭제된 트리거를 다시 DROP하려 할 때 에러를 방지하려면 존재 여부를 먼저 체크하거나 예외 처리를 사용하세요.
-- 방법 1: 존재 확인 후 DROP (PL/SQL 활용)
DECLARE
v_count NUMBER;
BEGIN
SELECT COUNT(*)
INTO v_count
FROM USER_TRIGGERS
WHERE TRIGGER_NAME = 'TRG_ORDER_INSERT';
IF v_count > 0 THEN
EXECUTE IMMEDIATE 'DROP TRIGGER TRG_ORDER_INSERT';
DBMS_OUTPUT.PUT_LINE('트리거가 성공적으로 삭제되었습니다.');
ELSE
DBMS_OUTPUT.PUT_LINE('트리거가 존재하지 않아 삭제를 건너뜁니다.');
END IF;
END;
/
-- 방법 2: 예외 처리를 이용한 안전한 DROP
DECLARE
trg_not_exist EXCEPTION;
PRAGMA EXCEPTION_INIT(trg_not_exist, -4080);
BEGIN
EXECUTE IMMEDIATE 'DROP TRIGGER TRG_ORDER_INSERT';
DBMS_OUTPUT.PUT_LINE('트리거 삭제 완료.');
EXCEPTION
WHEN trg_not_exist THEN
DBMS_OUTPUT.PUT_LINE('ORA-04080: 트리거가 존재하지 않습니다. 작업을 건너뜁니다.');
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('예상치 못한 에러: ' || SQLERRM);
RAISE;
END;
/
-- 방법 3: 트리거 재생성 (DROP 없이 대체)
CREATE OR REPLACE TRIGGER TRG_ORDER_INSERT
BEFORE INSERT ON ORDERS
FOR EACH ROW
BEGIN
:NEW.CREATED_AT := SYSDATE;
:NEW.CREATED_BY := USER;
END;
/
예방 방법
1. 배포 스크립트에 조건부 DROP 패턴 표준화
개발팀 전체가 공유하는 배포 스크립트 템플릿에 위에서 소개한 EXCEPTION_INIT 패턴 또는 딕셔너리 조회 후 DROP하는 방식을 표준으로 정의하세요. CI/CD 파이프라인이나 Flyway, Liquibase 같은 DB 마이그레이션 도구를 사용하는 경우에도 트리거 존재 여부를 사전 검증하는 단계를 추가하면 운영 중 발생하는 불필요한 에러를 크게 줄일 수 있습니다.
2. 트리거 관리 대장 및 네이밍 컨벤션 수립
트리거 이름에 TRG_ 접두어와 테이블명, 이벤트 유형을 결합한 명확한 네이밍 컨벤션(예: TRG_ORDERS_BI – Before Insert)을 수립하고, 전체 트리거 목록을 주기적으로 DBA_TRIGGERS에서 점검하는 루틴을 수립하세요. 이렇게 하면 오타나 스키마 혼동으로 인한 에러를 사전에 방지할 수 있습니다.
관련 에러
- ORA-04098: 트리거가 INVALID 상태인 경우 DML 실행 시 발생하는 에러로, 트리거가 존재하지만 컴파일 오류로 사용 불가한 상태입니다.
- ORA-00942: 테이블 또는 뷰가 존재하지 않을 때 발생하며, 트리거가 참조하는 기반 테이블이 삭제된 경우 함께 발생할 수 있습니다.
- ORA-04021: 트리거를 포함한 객체에 락(Lock)이 걸려 있어 컴파일이나 변경 작업을 수행할 수 없을 때 발생합니다.
- ORA-01031: 트리거를 수정하거나 삭제할 권한이 부족한 경우 발생하는 권한 에러입니다.
주요 DBMS error code를 정리하는 시리즈입니다.
블로그 홈에서 다른 에러도 확인하세요.
본 포스트는 AI가 생성한 기술 가이드입니다. 운영 환경 적용 전 충분한 검토를 권장합니다.