2026년 07월 27일 | DBMS Error 가이드
이 글에서 다루는 내용
ORA-01720 에러의 원인 분석, 해결 SQL, 예방 방법을 실무 관점에서 정리합니다.
ORA-01720 grant option does not exist for 는?
ORA-01720 에러는 특정 객체(테이블, 뷰 등)에 대한 권한을 다른 사용자에게 부여(GRANT)하려 할 때, 해당 권한을 부여할 수 있는 GRANT OPTION 또는 ADMIN OPTION을 현재 사용자가 보유하고 있지 않을 때 발생합니다. 특히 뷰(View)를 기반으로 SELECT 권한을 전파하려 할 때 자주 발생하며, 뷰를 구성하는 기반 테이블(Base Table)에 대한 GRANT OPTION이 없는 경우 이 에러가 나타납니다. 실무에서는 복잡한 권한 구조를 가진 멀티 스키마 환경에서 빈번하게 마주치는 에러입니다.
주요 발생 원인
1. 뷰(View)의 기반 테이블에 대한 GRANT OPTION 누락
가장 흔한 발생 원인입니다. 사용자 A가 사용자 B의 테이블을 이용해 뷰를 만들었을 때, 사용자 B가 사용자 A에게 해당 테이블에 대한 권한을 WITH GRANT OPTION 없이 부여한 경우입니다. 이 상황에서 사용자 A가 자신의 뷰에 대한 SELECT 권한을 사용자 C에게 부여하려 하면 ORA-01720이 발생합니다. 뷰는 기반 테이블의 권한 체계를 그대로 상속받기 때문에 기반 테이블의 GRANT OPTION 유무가 결정적입니다.
2. WITH GRANT OPTION 없이 부여된 객체 권한을 재부여 시도
사용자가 특정 테이블이나 뷰에 대해 권한을 받았더라도, 그 권한이 WITH GRANT OPTION 없이 부여된 경우에는 해당 권한을 제3자에게 전달할 수 없습니다. 예를 들어, DBA가 GRANT SELECT ON hr.employees TO app_user;와 같이 단순 부여를 했다면, app_user는 다른 사용자에게 이 권한을 재부여할 수 없습니다. 이는 보안상 의도된 동작이지만, 권한 설계가 잘못된 경우 운영 중 에러로 이어집니다.
3. 시노님(Synonym)을 통한 간접 객체 참조 시 권한 체계 불일치
PUBLIC SYNONYM이나 PRIVATE SYNONYM을 통해 다른 스키마의 객체를 참조하는 뷰를 생성했을 때, 해당 시노님이 가리키는 실제 객체에 대한 GRANT OPTION이 없는 경우 이 에러가 발생합니다. 시노님은 객체 자체가 아니기 때문에 권한 체계는 항상 실제 기반 객체에 종속됩니다. 이 경우 시노님 레벨에서의 권한 관리만으로는 문제를 해결할 수 없으며, 원본 객체 소유자에게 GRANT OPTION 포함 권한 부여를 요청해야 합니다.
해결 방법
해결책 1: 기반 테이블 소유자가 WITH GRANT OPTION으로 권한 부여
뷰를 생성한 사용자(SCHEMA_A)가 기반 테이블 소유자(SCHEMA_B)로부터 WITH GRANT OPTION을 포함한 권한을 받아야 합니다.
-- SCHEMA_B (기반 테이블 소유자)가 실행
-- 기존의 단순 GRANT를 먼저 취소
REVOKE SELECT ON schema_b.employees FROM schema_a;
-- WITH GRANT OPTION을 포함하여 재부여
GRANT SELECT ON schema_b.employees TO schema_a WITH GRANT OPTION;
-- 이제 SCHEMA_A는 자신의 뷰에 대한 권한을 제3자에게 부여 가능
-- SCHEMA_A가 실행
GRANT SELECT ON schema_a.emp_view TO schema_c;
해결책 2: 권한 현황 조회 및 GRANT OPTION 보유 여부 확인
문제를 해결하기 전에 반드시 현재 권한 구조를 조회해야 합니다.
-- 현재 사용자가 보유한 객체 권한과 GRANT OPTION 여부 확인
SELECT GRANTEE,
OWNER,
TABLE_NAME,
PRIVILEGE,
GRANTABLE, -- YES이면 GRANT OPTION 보유, NO이면 미보유
HIERARCHY
FROM DBA_TAB_PRIVS
WHERE GRANTEE = 'SCHEMA_A'
ORDER BY TABLE_NAME, PRIVILEGE;
-- 뷰의 기반 테이블 정보 조회 (뷰가 참조하는 객체 확인)
SELECT VIEW_NAME,
REFERENCED_OWNER,
REFERENCED_NAME,
REFERENCED_TYPE
FROM DBA_DEPENDENCIES
WHERE NAME = 'EMP_VIEW'
AND OWNER = 'SCHEMA_A'
AND REFERENCED_TYPE = 'TABLE';
해결책 3: DBA 권한을 이용한 직접 부여 (긴급 조치)
DBA가 직접 개입하여 WITH GRANT OPTION을 설정하거나, 뷰 대신 시노님 구조를 재설계합니다.
-- DBA 계정으로 실행: 뷰 기반 테이블에 GRANT OPTION 일괄 부여
BEGIN
FOR rec IN (
SELECT REFERENCED_OWNER, REFERENCED_NAME
FROM DBA_DEPENDENCIES
WHERE NAME = 'EMP_VIEW'
AND OWNER = 'SCHEMA_A'
AND REFERENCED_TYPE = 'TABLE'
) LOOP
EXECUTE IMMEDIATE
'GRANT SELECT ON ' || rec.REFERENCED_OWNER || '.' ||
rec.REFERENCED_NAME || ' TO SCHEMA_A WITH GRANT OPTION';
END LOOP;
END;
/
-- 또는 뷰 대신 시노님(Synonym)을 사용하는 방식으로 우회
-- DBA가 PUBLIC SYNONYM 생성 후 PUBLIC 권한 부여
CREATE OR REPLACE PUBLIC SYNONYM emp_pub_syn FOR schema_b.employees;
GRANT SELECT ON schema_b.employees TO PUBLIC;
해결책 4: 권한 체인 전체 재설계
장기적으로 올바른 해결을 위해 권한 구조 전체를 다시 점검합니다.
-- Step 1: 현재 GRANT 체인 전체 조회 (그랜트 체인 추적)
SELECT GRANTEE,
OWNER || '.' || TABLE_NAME AS OBJECT_NAME,
PRIVILEGE,
GRANTABLE,
GRANTED_BY
FROM DBA_TAB_PRIVS
WHERE TABLE_NAME IN (
SELECT REFERENCED_NAME
FROM DBA_DEPENDENCIES
WHERE NAME = 'EMP_VIEW' AND OWNER = 'SCHEMA_A'
)
ORDER BY GRANTABLE DESC, GRANTEE;
-- Step 2: 올바른 순서로 권한 재구성
-- 원본 소유자 → 뷰 소유자 (WITH GRANT OPTION)
GRANT SELECT ON schema_b.employees TO schema_a WITH GRANT OPTION;
GRANT SELECT ON schema_b.departments TO schema_a WITH GRANT OPTION;
-- Step 3: 뷰 소유자 → 최종 사용자
GRANT SELECT ON schema_a.emp_view TO schema_c;
GRANT SELECT ON schema_a.emp_view TO schema_d;
예방 방법
1. 권한 설계 단계에서 GRANT OPTION 필요 여부를 사전에 정의하고 문서화하기
멀티 스키마 환경에서 뷰를 생성하거나 권한을 위임해야 하는 경우, 설계 단계에서 GRANT OPTION이 필요한 객체를 사전에 식별해야 합니다. 권한 매트릭스 문서를 작성하여 어떤 사용자가 어떤 객체에 대해 GRANT OPTION을 보유해야 하는지 명확히 정의하고, 신규 뷰 생성 또는 스키마 변경 시 해당 문서를 반드시 참조하도록 팀 내 프로세스를 수립해야 합니다. 이렇게 하면 운영 중 갑작스러운 ORA-01720 발생을 사전에 차단할 수 있습니다.
-- 권한 현황 정기 점검 스크립트 (월 1회 실행 권장)
SELECT D.OWNER AS VIEW_OWNER,
D.NAME AS VIEW_NAME,
D.REFERENCED_OWNER,
D.REFERENCED_NAME,
NVL(P.GRANTABLE, 'NO_GRANT') AS GRANT_OPTION_STATUS
FROM DBA_DEPENDENCIES D
LEFT JOIN DBA_TAB_PRIVS P
ON P.GRANTEE = D.OWNER
AND P.OWNER = D.REFERENCED_OWNER
AND P.TABLE_NAME = D.REFERENCED_NAME
AND P.PRIVILEGE = 'SELECT'
WHERE D.TYPE = 'VIEW'
AND D.REFERENCED_TYPE = 'TABLE'
AND (P.GRANTABLE IS NULL OR P.GRANTABLE = 'NO')
ORDER BY D.OWNER, D.NAME;
2. 역할(Role) 기반 권한 관리 체계 도입으로 직접 GRANT 최소화하기
개별 사용자에게 직접 권한을 부여하는 방식 대신, 역할(Role)을 통한 권한 관리 체계를 도입하면 GRANT OPTION 문제를 구조적으로 줄일 수 있습니다. 역할을 사용하면 권한 변경 시 역할만 수정하면 되므로 권한 추적과 관리가 용이합니다. 단, 역할에 부여된 권한은 저장 프로시저나 뷰 내부에서는 활성화되지 않으므로, 이 경우에는 직접 권한 부여(GRANT ... WITH GRANT OPTION)가 필요하다는 점도 팀 내에서 반드시 공유해야 합니다.
관련 에러
- ORA-01031 (insufficient privileges): GRANT OPTION 없이 권한 부여를 시도하거나, 접근 권한 자체가 없는 객체에 접근할 때 발생합니다. ORA-01720과 혼동될 수 있으며, 권한 부여 단계가 아닌 객체 접근 단계에서 발생하는 점이 다릅니다.
- ORA-04042 (procedure, function, package, or package body does not exist): 프로시저 또는 함수에 대한 EXECUTE 권한을 WITH GRANT OPTION 없이 재부여하려 할 때 복합적으로 발생할 수 있습니다.
- ORA-01749 (you may not GRANT/REVOKE privileges to/from yourself): 권한 부여 구조를 재설계하는 과정에서 자기 자신에게 권한을 부여하려 할 때 발생할 수 있는 연관 에러입니다.
주요 DBMS error code를 정리하는 시리즈입니다.
블로그 홈에서 다른 에러도 확인하세요.
본 포스트는 AI가 생성한 기술 가이드입니다. 운영 환경 적용 전 충분한 검토를 권장합니다.