소스: sql-src/mid_11_view_sequence/01_view.sql. dept(부서)와 emp(직원 6명) 테이블을 준비했습니다.
CREATE VIEW dept_summary AS
SELECT
d.code AS dept
, d.dname AS dname
, COUNT(*) AS emp_cnt
, SUM(e.sal) AS total_sal
FROM emp e
JOIN dept d ON d.code = e.dept
GROUP BY d.code, d.dname;
SELECT
dept
, dname
, emp_cnt
, total_sal
FROM dept_summary
ORDER BY dept;DEPT | DNAME | EMP_CNT | TOTAL_SAL
-----+------------+---------+----------
개발 | 개발팀 | 3 | 1350
경영 | 경영지원팀 | 1 | 900
영업 | 영업팀 | 2 | 870
(3행)dept_summary 를 조회하는 쪽은 조인과 GROUP BY 를 몰라도 됩니다. 부서별 인원·급여 합계를 매번 새로 조인해 계산하는 대신 뷰 이름만 조회하면 됩니다.
CREATE VIEW emp_public AS
SELECT
id
, name
, dept
FROM emp;
SELECT
id
, name
, dept
FROM emp_public
ORDER BY id;
-- @error
SELECT sal FROM emp_public;
-- DROP 없이 CREATE OR REPLACE VIEW 로 정의를 바꾼다
CREATE OR REPLACE VIEW emp_public AS
SELECT
id
, name
, dept
, hired
FROM emp;
SELECT
id
, name
, dept
, hired
FROM emp_public
ORDER BY id;ID | NAME | DEPT
---+--------+-----
1 | 김대표 | 경영
2 | 이팀장 | 개발
3 | 박선임 | 개발
4 | 최사원 | 개발
5 | 정팀장 | 영업
6 | 한사원 | 영업
(6행)
예상 오류: Column "SAL" not found
ID | NAME | DEPT | HIRED
---+--------+------+-----------
1 | 김대표 | 경영 | 2020-01-02
2 | 이팀장 | 개발 | 2021-03-01
3 | 박선임 | 개발 | 2022-05-10
4 | 최사원 | 개발 | 2024-02-01
5 | 정팀장 | 영업 | 2021-07-15
6 | 한사원 | 영업 | 2023-09-01
(6행)emp_public 뷰의 정의에는 처음에 sal(급여) 컬럼이 없어, 이 뷰만 조회 권한을 준 사용자는 급여를 볼 방법이 없습니다. DROP VIEW 없이 CREATE OR REPLACE VIEW 로 hired 컬럼을 추가했고, 기존 뷰에 걸린 조회 권한도 그대로 유지됩니다.
CREATE VIEW emp_dev AS
SELECT
id
, name
, dept
, sal
FROM emp
WHERE dept = '개발';
SELECT
id
, name
, sal
FROM emp_dev
ORDER BY id;ID | NAME | SAL
---+--------+----
2 | 이팀장 | 600
3 | 박선임 | 450
4 | 최사원 | 300
(3행)emp_dev 는 테이블 하나(emp)만 참조하고 집계가 없어 2.3절 조건을 만족합니다. 실제 Oracle·MySQL·MSSQL 이라면 이 뷰를 통한 UPDATE 가 원본 테이블에 그대로 반영됩니다.
-- H2 는 단순 단일 테이블 뷰라도 뷰를 통한 UPDATE 를 지원하지 않는다
-- @error
UPDATE emp_dev SET sal = sal + 10 WHERE id = 2;예상 오류: Feature not supported: "TableView.removeRow"-- 실제 DB 도 dept_summary 는 집계 뷰라 UPDATE 를 거부한다
-- @error
UPDATE dept_summary SET emp_cnt = 0 WHERE dept = '개발';예상 오류: Feature not supported: "TableView.removeRow"dept_summary 는 JOIN·GROUP BY·SUM 이 모두 섞여 있어 실제 DB 도 이 뷰를 통한 UPDATE 를 거부합니다. H2 오류 메시지는 예제 3 과 같지만 실제 DB 에서는 이유가 다릅니다. 예제 3 은 조건을 만족하는데 H2 가 못 하는 경우이고, 이 예제는 조건 자체를 어겨 실제 DB 도 막는 경우입니다.
-- H2 는 CREATE VIEW 문법 자체에서 WITH CHECK OPTION 을 받아들이지 않는다
-- @error
CREATE VIEW emp_dev_checked AS SELECT id, name, dept, sal FROM emp WHERE dept = '개발' WITH CHECK OPTION;예상 오류: Syntax error in SQL statement "CREATE VIEW emp_dev_checked AS SELECT id, name, dept, sal FROM emp WHERE dept = '개발' [*]WITH CHECK OPTION"실제 DB 라면 이 뷰가 만들어진 뒤 UPDATE emp_dev_checked SET dept = '영업' WHERE id = 2; 처럼 뷰 조건(dept = '개발')을 벗어나는 수정을 시도하면 거부됩니다. 부서를 바꾸는 순간 그 행이 더 이상 뷰 조건을 만족하지 않기 때문입니다. 뷰를 지울 때는 DROP VIEW 이름; 을 쓰며 세 DB 모두 같은 문법입니다.