在 Oracle 資料庫中,並非所有視圖都支援直接插入數據。能否對視圖執行 INSERT、UPDATE、DELETE 操作,取決於視圖的定義方式:
若視圖僅基於單一基礎表建立,即為「非連接視圖」。此類視圖預設即可更新,可直接執行 DML 操作,無額外限制。
涉及多張表關聯的視圖稱為「連接視圖」,插入數據時必須遵循嚴格的「碼保留表」規則:
EMP 表的 EMP_NO 仍為主鍵)。DEPT 表的 DEPT_NO 在視圖中不再唯一)。插入限制:INSERT 語句不得明確或隱含引用任何非碼保留基礎表的欄位;若視圖定義包含 WITH CHECK OPTION 子句,則完全禁止對該視圖執行 INSERT 操作。
CREATE VIEW emp_dept AS
SELECT emp.emp_no, emp.emp_name, emp.dept_no, dept.name
FROM emp, dept
WHERE emp.dept_no = dept.dept_no;
此視圖中 EMP_NO 仍具唯一性,故 EMP 為碼保留表;DEPT_NO 在視圖中重複出現,DEPT 為非碼保留表。依規則,僅能插入 EMP 表欄位的數據。
針對多表關聯視圖的插入需求,建議採用 INSTEAD OF 觸發器 替代直接 DML,將邏輯封裝於觸發器中,分別寫入各基礎表:
CREATE TRIGGER trig_name
ON view_name
INSTEAD OF INSERT
AS
BEGIN
-- 宣告變數
-- 從 inserted 表取得所有欄位值
-- 寫入第一張基礎表
-- 寫入第二張基礎表
END;
可查詢 USER_UPDATABLE_COLUMNS 視圖,快速確認某表或視圖的欄位是否可更新:
SELECT * FROM USER_UPDATABLE_COLUMNS WHERE TABLE_NAME = 'YOUR_VIEW';