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

ORA-01732
2026년 07월 28일 | DBMS Error 가이드

이 글에서 다루는 내용

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

ORA-01732 data manipulation operation not legal on this view 는?

ORA-01732 에러는 Oracle 데이터베이스에서 뷰(View)에 대해 INSERT, UPDATE, DELETE와 같은 DML(Data Manipulation Language) 작업을 시도할 때 해당 뷰가 그러한 작업을 허용하지 않는 구조일 경우 발생합니다. 즉, 특정 뷰는 데이터를 읽는 용도로만 사용 가능하며, 뷰를 통한 데이터 변경이 구조적으로 불가능할 때 Oracle이 이 에러를 반환합니다. 실무에서는 복잡한 조인, 집계 함수, DISTINCT, GROUP BY 등을 포함한 뷰에 DML을 시도할 때 자주 마주치는 에러입니다.


주요 발생 원인

1. 집계 함수(Aggregate Function) 또는 GROUP BY를 포함한 뷰에 DML 시도

뷰 정의에 SUM, AVG, COUNT, MAX, MIN과 같은 집계 함수나 GROUP BY 절이 포함되어 있으면, 해당 뷰는 여러 행의 데이터를 하나로 합쳐서 보여주기 때문에 Oracle은 원본 테이블의 어느 행을 수정해야 할지 판단할 수 없습니다. 따라서 이러한 뷰에 대한 INSERT, UPDATE, DELETE는 구조적으로 불가능하며 ORA-01732가 발생합니다.

2. 여러 테이블을 조인(JOIN)하는 뷰에 DML 시도

두 개 이상의 테이블을 조인하여 생성된 뷰의 경우, 특정 조건을 만족하지 않으면 DML 작업이 허용되지 않습니다. Oracle은 조인 뷰에서 DML을 허용하기 위한 키 보존(Key-Preserved) 조건을 요구하는데, 조인 대상 테이블 중 하나 이상이 기본 키(Primary Key)나 유니크 키를 통해 행을 고유하게 식별할 수 없으면 이 에러가 발생합니다.

3. DISTINCT, ROWNUM, SET 연산자(UNION, INTERSECT, MINUS)를 포함한 뷰에 DML 시도

DISTINCT 키워드, ROWNUM 의사 컬럼, 또는 UNION/INTERSECT/MINUS와 같은 집합 연산자를 포함한 뷰는 Oracle이 원본 데이터와의 1:1 매핑을 보장할 수 없으므로 DML이 원천적으로 차단됩니다. 이러한 뷰는 데이터 조회 전용으로 설계된 것으로, 데이터 변경이 필요하다면 반드시 원본 테이블에 직접 DML을 수행해야 합니다.


해결 방법

원인 1 해결: 집계 함수/GROUP BY를 포함한 뷰 — 원본 테이블에 직접 DML 수행

집계 뷰를 통한 DML 대신, 원본 테이블을 직접 수정해야 합니다.

-- 문제가 되는 뷰 정의 예시
CREATE OR REPLACE VIEW v_dept_salary AS
SELECT department_id, SUM(salary) AS total_salary
FROM employees
GROUP BY department_id;

-- 아래와 같이 뷰에 UPDATE를 시도하면 ORA-01732 발생
-- UPDATE v_dept_salary SET total_salary = 50000 WHERE department_id = 10;

-- 해결책: 원본 테이블(employees)에 직접 UPDATE
UPDATE employees
SET salary = salary * 1.1
WHERE department_id = 10;

COMMIT;

원인 2 해결: 조인 뷰에서 INSTEAD OF 트리거 활용

조인 뷰에 DML이 필요한 경우, INSTEAD OF 트리거를 생성하여 DML 요청을 가로채 원본 테이블에 적절히 처리할 수 있습니다.

-- 조인 뷰 정의
CREATE OR REPLACE VIEW v_emp_dept AS
SELECT e.employee_id, e.first_name, e.salary, d.department_name
FROM employees e
JOIN departments d ON e.department_id = d.department_id;

-- INSTEAD OF 트리거 생성
CREATE OR REPLACE TRIGGER trg_emp_dept_update
INSTEAD OF UPDATE ON v_emp_dept
FOR EACH ROW
BEGIN
    -- employees 테이블만 업데이트 (salary 변경)
    UPDATE employees
    SET salary = :NEW.salary
    WHERE employee_id = :OLD.employee_id;
END;
/

-- 이제 뷰를 통한 UPDATE가 트리거를 통해 처리됨
UPDATE v_emp_dept
SET salary = 8000
WHERE employee_id = 100;

COMMIT;

원인 3 해결: DISTINCT/UNION 뷰 — 원본 쿼리로 직접 DML 수행

-- 문제가 되는 뷰 (UNION 포함)
CREATE OR REPLACE VIEW v_all_employees AS
SELECT employee_id, first_name FROM employees WHERE department_id = 10
UNION
SELECT employee_id, first_name FROM employees WHERE department_id = 20;

-- 뷰에 INSERT 시도 시 ORA-01732 발생
-- INSERT INTO v_all_employees VALUES (9999, 'TestUser'); -- 에러!

-- 해결책: 원본 테이블에 직접 INSERT
INSERT INTO employees (employee_id, first_name, department_id, ...)
VALUES (9999, 'TestUser', 10, ...);

COMMIT;

뷰의 DML 가능 여부 사전 확인 방법

-- USER_UPDATABLE_COLUMNS 뷰를 통해 DML 가능 여부 확인
SELECT column_name, updatable, insertable, deletable
FROM user_updatable_columns
WHERE table_name = 'V_EMP_DEPT';

-- ALL_VIEWS에서 뷰 정의 확인
SELECT view_name, text
FROM all_views
WHERE view_name = 'V_EMP_DEPT';

예방 방법

1. 뷰 생성 시 DML 가능 여부를 명확히 문서화하고 WITH READ ONLY 옵션 활용

DML이 불가능한 뷰에는 명시적으로 WITH READ ONLY 옵션을 부여하여, 개발자가 실수로 해당 뷰에 DML을 시도할 때 ORA-01733(읽기 전용 뷰 에러)으로 명확한 메시지를 받을 수 있도록 설계하는 것이 좋습니다. 또한 뷰의 주석(COMMENT)에 사용 목적과 DML 가능 여부를 반드시 기재하는 팀 내 코딩 컨벤션을 수립하세요.

-- 읽기 전용 뷰 명시적 선언
CREATE OR REPLACE VIEW v_dept_summary AS
SELECT department_id, COUNT(*) AS emp_count, AVG(salary) AS avg_salary
FROM employees
GROUP BY department_id
WITH READ ONLY;

-- 뷰에 주석 추가
COMMENT ON TABLE v_dept_summary IS '부서별 요약 통계 뷰 - 읽기 전용, DML 불가';

2. 조인 뷰 설계 시 Key-Preserved 조건 사전 검토 및 INSTEAD OF 트리거 패턴 표준화

조인 뷰를 설계할 때는 반드시 USER_UPDATABLE_COLUMNS 딕셔너리 뷰를 통해 DML 가능 여부를 사전에 확인하고, DML이 필요한 복잡한 뷰에는 프로젝트 초기부터 INSTEAD OF 트리거 패턴을 표준으로 적용하세요. 이를 통해 애플리케이션 코드에서 뷰를 통한 DML을 자연스럽게 사용하면서도 데이터 무결성을 유지할 수 있습니다.


관련 에러

  • ORA-01733: virtual column not allowed here — WITH READ ONLY로 선언된 뷰에 DML을 시도할 때 발생하며, ORA-01732와 유사한 맥락입니다.
  • ORA-01779: cannot modify a column which maps to a non key-preserved table — 조인 뷰에서 키 보존이 되지 않는 테이블의 컬럼을 수정하려 할 때 발생합니다.
  • ORA-01776: cannot modify more than one base table through a join view — 하나의 DML문으로 조인 뷰를 통해 두 개 이상의 기본 테이블을 동시에 수정하려 할 때 발생합니다.

DBMS 에러 코드 시리즈

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

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

댓글 남기기