單表 View 可直接 DML;但跨多表(JOIN)建立的 View 預設不可插入/更新/刪除,嘗試會報 ORA-01779: cannot modify a column which maps to a non key-preserved table。
在 View 上建立 INSTEAD OF 觸發器,攔截 DML 並轉發至基底表:
CREATE OR REPLACE TRIGGER trg_v_multi_io
INSTEAD OF INSERT OR UPDATE OR DELETE ON v_multi
FOR EACH ROW
DECLARE
BEGIN
IF INSERTING THEN
INSERT INTO base_tbl1 (col1, col2) VALUES (:NEW.f1, :NEW.f2);
INSERT INTO base_tbl2 (col1, col3) VALUES (:NEW.f1, :NEW.f3);
ELSIF UPDATING THEN
UPDATE base_tbl1 SET col1 = :NEW.f1, col2 = :NEW.f2 WHERE col1 = :OLD.f1;
UPDATE base_tbl2 SET col1 = :NEW.f1, col3 = :NEW.f3 WHERE col1 = :OLD.f1;
ELSIF DELETING THEN
DELETE FROM base_tbl1 WHERE col1 = :OLD.f1;
DELETE FROM base_tbl2 WHERE col1 = :OLD.f1;
END IF;
END;
/
:NEW 代表新值,:OLD 代表舊值。INSTEAD OF TRIGGER 是多表 View 可更新化的標準手段,將「視圖邏輯」與「基底表寫入邏輯」解耦,符合封裝原則。生產環境務必配合單元測試驗證各 DML 情境。