| 視圖類型 | 定義 | 可直接 INSERT/UPDATE/DELETE |
|---|---|---|
| 非連接視圖 | 單一基礎表衍生 | ✅ 是(預設可更新) |
| 連接視圖 | 多表 JOIN 衍生 | ❌ 否(需遵循關鍵保留表規則或建立 INSTEAD OF Trigger) |
連接視圖中,若某基礎表的主鍵在視圖中**保持唯一**,該表為「關鍵保留表」,可直接更新其非鍵欄位;非關鍵保留表的欄位**不可直接更新/插入**。
-- 範例:EMP (PK=EMPNO) 關聯 DEPT (PK=DEPTNO)
CREATE VIEW emp_dept AS
SELECT e.empno, e.ename, e.deptno, d.dname
FROM emp e, dept d
WHERE e.deptno = d.deptno;
-- EMP 為關鍵保留表(EMPNO 仍唯一),DEPT 非關鍵保留表
-- 可直接 UPDATE emp_dept SET ename='X' WHERE empno=1;
-- 不可直接 INSERT INTO emp_dept VALUES (..., 'New Dept'); -- 會報錯
CREATE OR REPLACE TRIGGER emp_dept_iot
INSTEAD OF INSERT ON emp_dept
FOR EACH ROW
BEGIN
-- 1. 插入/更新 DEPT(非關鍵保留表)
MERGE INTO dept d
USING (SELECT :NEW.deptno AS deptno, :NEW.dname AS dname FROM dual) src
ON (d.deptno = src.deptno)
WHEN MATCHED THEN UPDATE SET dname = src.dname
WHEN NOT MATCHED THEN INSERT (deptno, dname) VALUES (src.deptno, src.dname);
-- 2. 插入 EMP(關鍵保留表)
INSERT INTO emp (empno, ename, deptno)
VALUES (:NEW.empno, :NEW.ename, :NEW.deptno);
END;
/
-- 現在可直接 INSERT INTO emp_dept VALUES (9999, 'NewEmp', 50, 'NewDept');
SELECT * FROM user_updatable_columns WHERE table_name = 'EMP_DEPT';
結果顯示哪些欄位可直接更新,哪些需 Trigger。