首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> Oracle 資料庫 >> Oracle 資料庫基礎

Oracle View 建立語法詳解與進階應用模式

     編輯:Oracle 資料庫基礎

視圖是邏輯層封裝、安全控制與查詢簡化的核心工具。本文系統講解 CREATE VIEW 完整語法、簡單/複雜視圖差異、WITH CHECK OPTION / READ ONLY 限制機制,以及不可更新視圖的 INSTEAD OF 觸發器解法。

完整語法圖解

CREATE [OR REPLACE] [FORCE | NOFORCE] VIEW view_name
  [ (alias [, alias] ...) ]
AS subquery
[ WITH CHECK OPTION [CONSTRAINT constraint_name] ]
[ WITH READ ONLY ]; 

關鍵字選項深度解析

經典範例:部門薪資彙總視圖

CREATE OR REPLACE VIEW dept_salary_vw (
  dept_name, min_sal, max_sal, avg_sal, emp_cnt
) AS
SELECT d.dname,
       MIN(e.sal), MAX(e.sal), AVG(e.sal), COUNT(*)
FROM emp e
JOIN dept d ON e.deptno = d.deptno
GROUP BY d.dname
WITH READ ONLY;  -- 報表視圖禁止寫入

簡單視圖 vs 複雜視圖 (可更新性判斷)

選項行為適用場景
OR REPLACE視圖存在則重建,保留權限與相依物件開發迭代、腳本重跑
FORCE基表不存在也強制建立 (編譯時驗證)部署腳本順序不固定、跨 Schema 參考
NOFORCE (預設)基表必須存在且有權限嚴格模式
alias 別名清單為 SELECT 列指定顯示名稱,須與列數一致隱藏原欄名、統一報表介面
WITH CHECK OPTIONDML 操作必須符合視圖 WHERE 條件,否則報錯資料隔離、多租戶安全
WITH READ ONLY禁止任何 DML (INSERT/UPDATE/DELETE)唯讀報表、防誤改
特徵簡單視圖 (可直接 DML)複雜視圖 (需 INSTEAD OF Trigger)
基表數量單一基表多表 JOIN
聚合/分組無 GROUP BY / 聚合函數有 GROUP BY、DISTINCT、聚合
集合運算無 UNION/INTERSECT/MINUS有集合運算
子查詢無子查詢 (或僅標量子查詢)包含子查詢
虛擬欄/運算式無衍生欄位有運算式、函數結果欄
WITH CHECK OPTION支援不支援 (需觸發器實現)

進階模式 1:安全性隔離 - WITH CHECK OPTION

-- 僅允許存取自己部門資料
CREATE OR REPLACE VIEW emp_self_vw AS
SELECT empno, ename, sal, deptno
FROM emp
WHERE deptno = SYS_CONTEXT('USERENV', 'CLIENT_IDENTIFIER')  -- 應用設定 Context
WITH CHECK OPTION;  -- 防止 UPDATE deptno 竄改他部門資料

進階模式 2:複雜視圖寫入 - INSTEAD OF TRIGGER

CREATE OR REPLACE VIEW emp_dept_vw AS
SELECT e.empno, e.ename, e.sal, d.dname, d.loc
FROM emp e JOIN dept d ON e.deptno = d.deptno;

CREATE OR REPLACE TRIGGER emp_dept_vw_iud
INSTEAD OF INSERT OR UPDATE OR DELETE ON emp_dept_vw
FOR EACH ROW
DECLARE
  v_deptno dept.deptno%TYPE;
BEGIN
  IF INSERTING OR UPDATING THEN
    -- 確保部門存在或自動建立
    SELECT deptno INTO v_deptno FROM dept WHERE dname = :NEW.dname;
    EXCEPTION WHEN NO_DATA_FOUND THEN
      SELECT dept_seq.NEXTVAL INTO v_deptno FROM dual;
      INSERT INTO dept (deptno, dname, loc) VALUES (v_deptno, :NEW.dname, :NEW.loc);
  END IF;

  IF INSERTING THEN
    INSERT INTO emp (empno, ename, sal, deptno)
    VALUES (:NEW.empno, :NEW.ename, :NEW.sal, v_deptno);
  ELSIF UPDATING THEN
    UPDATE emp SET ename = :NEW.ename, sal = :NEW.sal, deptno = v_deptno
    WHERE empno = :OLD.empno;
  ELSIF DELETING THEN
    DELETE FROM emp WHERE empno = :OLD.empno;
  END IF;
END;
/

視圖效能優化技巧

  • Predicate Pushing:優化器會嘗試將外層 WHERE 條件下推至視圖內部,複雜視圖可能受阻,可用 /*+ PUSH_PRED(view_alias) */ 強制。
  • Materialized View 替代:極複雜聚合視圖頻繁查詢,改用 MV + 定時刷新,查詢效能提升數量級。
  • 版本控管:OR REPLACE 會導致相依 PL/SQL 失效 (需重編譯),生產環境建議 DROP VIEW ... CASCADE CONSTRAINTS 後重建,並同步部署相依程式碼。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved