最近在處理公司 EIP 資料庫時,我遇到一個看似「超簡單」的需求:
把員工資料表 ORG_EMPLOYEE 裡的 Email 網域,從舊的 @old.com.tw
改成新的 @new.com.tw。
原本以為只是 UPDATE ... SET EMAIL = REPLACE(...) 的等級,沒想到一路從
Email 替換,延伸出:
這篇就是我在這段過程中的技術筆記:
我從一個簡單的更新開始,一路拆解到「企業資料庫完整性」的全貌。
原本以為:
UPDATE KGEIP.ORG_EMPLOYEE
SET EMAIL = REPLACE(EMAIL, '@old.com.tw', '@new.com.tw')
WHERE EMAIL LIKE '%@old.com.tw';
就能解決全部問題。
但更新之前我想到一件事:
如果資料表有 Trigger,而我沒有給完整欄位值,會不會讓 Trigger 報錯?
在企業級資料表中,MFDAT、MFMAN 等 audit
欄位非常常見,而這些欄位在不同系統裡可能被 Trigger 規範得很嚴。
我開始檢查 Trigger,發現該表沒有。但這也讓我回頭重新審視:
Trigger 到底應該扮演什麼角色?
Trigger 幾乎每個工程師都碰過,但它的「真實定位」常被誤解成只是審計使用。
其實 Trigger 在企業系統裡主要負責三件事:
例如自動生成修改時間:
:NEW.MFDAT := SYSDATE;
例如不同表間名稱同步。
例如 INSERT/UPDATE/DELETE 時紀錄變動。
而這些 Trigger 的行為會在所有 DML 之後「無條件執行」,也就是:
程式怎麼寫不重要,最後都會由 Trigger 兜底。
這種設計強大,但也有另一面:
Trigger 用得好很強,用不好就變「企業級黑箱」。
這次更新讓我徹底釐清三者的本質。
以下是我整理的比較表:
| 項目 | Trigger | Stored Procedure | Constraint |
|---|---|---|---|
| 角色定位 | 自動反應的邏輯 | 可控的業務流程 | 基本格式與關聯 |
| 執行時機 | 被動、DML 時觸發 | 主動呼叫 | 任何 DML 自動驗證 |
| 可處理複雜度 | 中等 | 高 | 低 |
| 維護成本 | 高 | 中 | 低 |
| 典型用途 | Audit、補值、跨表同步 | 批次、計算、流程控制 | Unique、FK、Check |
一句話總結:
三者不是替代關係,而是三層不同防線。
最常見的架構:
好處:
但也會遇到:
Audit 應該被系統化,而不是硬寫 Trigger。
Flashback 解的是:
我想知道 5 分鐘前資料長怎樣?
但不是:
誰改了什麼欄位?
Flashback 適用:
不能取代:
Flashback 是時光機,不是記錄器。
ROLLBACK。
Flashback Query → insert 回現表。
DDL → 隱含 commit → 幾乎不能救
只能依賴:
若有 recycle bin → FLASHBACK TABLE
否則只能備份還原。
真正的搶救流程:
關鍵反省:
如果開發者能 TRUNCATE 正式機,那是權限問題,不是技術問題。
我正在處理 Oracle/企業資料庫需求,請你從系統架構角度給我:
1. 支持性分析:確認我目前做法哪裡合理
2. 對立性視角:指出我沒看到的技術風險與盲點
3. 如果可能,提供安全的 SQL、Trigger/Audit 設計建議、恢復策略