DB Oracle

[Oracle] VIEW

아잠만_ 2024. 3. 28. 19:16

VIEW

CREATE [OR REPLACE] VIEW  뷰이름[ (컬럼list) ] AS
   SELECT 문
   [WITH CHECK OPTION]
   [WITH READ ONLY]
  • 'OR REPLACE' : 이름이 동일한 뷰가 이미 있으면 대치하고 없으면 새롭게 생성
  • '컬럼list' : 뷰에서 사용할 컬럼명들. 생략하면 SELECT문에 사용된 컬럼의 별칭이 뷰의
    컬럼명이 되며, SELECT문에서 별칭을 사용하지 않은 경우 SELECT문의 컬럼명이 뷰의 컬럼명이 됨
  • WITH CHECK OPTION : SELECT 문의 WHERE 절을 위배하는 DML명령을 뷰에 적용할 수 없다 ( 원본 테이블은 WITH CHECK OPTION에 상관없이 DML명령을 수행할 수 있다)
    (조건을 만족하는 범위는 뷰/테이블 바뀜 / 테이블은 상관없이 변경되며 뷰 또한 변경)
  • WITH READ ONLY : 읽기 전용 뷰를 생성함(뷰만 바뀜)
  • WITH CHECK OPTION와 WITH READ ONLY는 같이 사용할 수 없다.
  • 가상의 테이블
  • 기존의 테이블이나 뷰를 이용하여 SELECT문을 수행한 결과 집합
  • VIEW를 사용하는 경우
    - 필요한 정보가 복수개의 테이블에 분산되어 있는 경우
    - 특정자료에 대한 접근을 제한해야 하는 경우
    - 필요한 자료를 반환하기 위하여 매우 복잡한 동일한 서브쿼리를 매번 실행해야 하는 경우
    - 주기적으로 변동되는 쿼리의 결과를 이용해야 하는 경우 (그래프로 변동 상황을 자주 갱신하여 나타내야 하는 경우)
  • 테이블에서 내용이 UPDATE 될 경우 자동으로 VIEW에서도 UPDATE된다. (반대도 동일)
    WITH READ ONLY인 경우에는 UPDATE가 되지 않는다.
  • OR REPLACE 의 키워드로 인해 다시 CREATE를 해도 정상적으로 작동된다

회원테이블에서 마일리지가 3000이상인 회원들의 회원번호, 회원명, 마일리지로 뷰를 생성하시오
CREATE OR REPLACE VIEW V_MEM_MILEAGE AS
    SELECT MEM_ID, MEM_NAME, MEM_MILEAGE
      FROM MEMBER
     WHERE MEM_MILEAGE>=3000;
    -- 컬럼의 별칭은 SELECT절에 AS를 사용해도 가능하고,
    -- 이름 옆 V_MEM_MILEAGE(VID,VNAME,VMILE) 형태도 가능하다
(조회)
 SELECT * FROM V_MEM_MILEAGE;
(뷰의 갱신)
  UPDATE V_MEM_MILEAGE
     SET MEM_MILEAGE = 8960
   WHERE MEM_ID='b001'
  -- 원본 TABLE값 또한 변경
(원본테이블 갱신)
 UPDATE MEMBER
    SET MEM_MILEAGE = 2960
    WHERE MEM_ID='b001'
    -- 뷰 조건에 만족하지 못하므로 뷰에서 삭제

CHECK OPTION

CREATE OR REPLACE VIEW V_MEM_MILEAGE
 AS
 SELECT MEM_ID AS 회원번호, MEM_NAME AS 회원명, MEM_MILEAGE AS 마일리지
   FROM MEMBER
  WHERE MEM_MILEAGE>=3000
 WITH CHECK OPTION;
UPDATE V_MEM_MILEAGE
   SET 마일리지 = 2960
 WHERE 회원번호='b001';
오류 보고 -
ORA-01402: view WITH CHECK OPTION where-clause violation
-- WHERE절을 위배하는 업데이트가 시행 ( 3000 마일리지 이하이므로 오류)
(원본테이블 갱신)
 UPDATE MEMBER
    SET MEM_MILEAGE = 1960
    WHERE MEM_ID='b001' 
  -- 정상 작동 VIEW에서 b001값 제거

CREATE OR REPLACE VIEW V_CNT_MEMBER
AS
    SELECT COUNT (*) AS CNT
     FROM MEMBER
    WHERE MEM_MILEAGE>=4000;

CREATE OR REPLACE VIEW V_CNT_MEMBER
  AS
    SELECT COUNT (*) AS CNT
     FROM MEMBER
    WHERE MEM_MILEAGE>=4000;

(조회)
SELECT * FROM V_CNT_MEMBER;