真實案例:測試環境誤將正式庫 com.taw_rm_user.password 全部更新為 123456,經過 10 天已有新增/修改使用者。直接匯入 10 天前的 DMP 會覆蓋新資料,不可接受。本文展示「備份現況 → 匯入舊版 → 精準合併 → 還原現況」四步驟零資料遺失恢復法。
com,核心表 taw_rm_user(user_id PK, password, ...)comtest,同結構表UPDATE comtest.taw_rm_user SET password = '123456'; (本意僅改測試庫,實則連到正式庫)exp 匯出檔 backup.dmp (含 taw_rm_user)comtest.taw_rm_user_bakcomtest.taw_rm_usertaw_rm_user 匯入測試庫 comtestcomtest.taw_rm_user-- 1. 備份測試庫現況
CREATE TABLE comtest.taw_rm_user_bak AS
SELECT * FROM comtest.taw_rm_user;
-- 2. 刪除測試庫表
DROP TABLE comtest.taw_rm_user;
-- 3. 匯入 DMP 至測試庫
imp userid=comtest/pwd@testdb file=backup.dmp tables=taw_rm_user fromuser=com touser=comtest
DECLARE
CURSOR c_old IS
SELECT user_id, password
FROM comtest.taw_rm_user; -- 匯入的舊版資料 (含正確密碼)
v_cnt NUMBER;
BEGIN
FOR r IN c_old LOOP
-- 僅更新正式庫中「已存在」的使用者
SELECT COUNT(*) INTO v_cnt
FROM com.taw_rm_user
WHERE user_id = r.user_id;
IF v_cnt > 0 THEN
UPDATE com.taw_rm_user
SET password = r.password
WHERE user_id = r.user_id;
END IF;
-- 不存在者 (新增使用者) 完全不動作
END LOOP;
COMMIT;
DBMS_OUTPUT.PUT_LINE('精準合併完成,更新筆數: ' || SQL%ROWCOUNT);
EXCEPTION
WHEN OTHERS THEN
ROLLBACK;
RAISE;
END;
/
DROP TABLE comtest.taw_rm_user;
CREATE TABLE comtest.taw_rm_user AS SELECT * FROM comtest.taw_rm_user_bak;
DROP TABLE comtest.taw_rm_user_bak;
| 原則 | 本案例體現 |
|---|---|
| 不覆蓋新資料 | 新增使用者保留正式庫現狀,不從舊版 DMP 覆蓋 |
| 最小權限變更 | 僅更新 password 欄位,其他欄位 (email, role, status...) 完全不動 |
| 可驗證、可回滾 | PL/SQL 區塊含 COMMIT/ROLLBACK、SQL%ROWCOUNT 回報、例外處理 |
| 隔離測試環境 | 所有中間操作在 comtest 進行,正式庫 com 僅執行最終 UPDATE |
| 方案 | 優點 | 缺點 | 適用場景 |
|---|---|---|---|
| 本文:精準合併 | 零資料遺失、欄位級控制、業務連續 | 需撰寫 PL/SQL、適合單表/少數表 | 核心表誤更新、有可靠備份、業務不能停 |
| 時間點恢復 (PITR) | 整庫一致、工具化 | 丟失誤操作後所有交易、需歸檔模式、停機 | 大範圍損壞、可接受資料倒退 |
| LogMiner 分析 Redo | 可見具體 SQL、精準反向 | 複雜、需歸檔、效能影響 | 無備份、需審計具體操作 |
| Flashback Table/Database | 秒級回滾、無停機 | 需啟用 Flashback、UNDO 保留足夠、影響整表 | 剛發生、UNDO 尚未覆寫 |
DML 觸發器記錄變更 或 Fine-Grained AuditingWHERE env = 'TEST')資料誤更新不可怕,可怕的是無預案、無演練。掌握「備份隔離 → 精準合併 → 最小變更」核心模式,能在壓力下冷靜執行零損失恢復。