快速調整 INSERT / UPDATE SQL 語法
最近遇到一個很常見的維運場景:兩台資料庫的資料需要補齊,但欄位又不是完全一致。原本我是直接用 DBeaver 產生 INSERT / UPDATE SQL,再手動把不需要的欄位從 Editor 裡面刪掉。結果欄位一多時,這種做法真的很傷眼睛,也很容易刪錯。
後來才發現,這件事其實可以先在資料檢視階段把欄位整理好,再來產生 SQL,效率差很多。
先講問題本質
這種需求通常不是單純的資料匯出,而是:
- A 資料庫有資料,B 資料庫也要補。
- 兩邊 schema 類似,但不完全一樣。
- 我只想同步少數欄位。
- 還想保留人工檢查 SQL 的能力。
如果直接從完整結果集產生 SQL,再手動刪欄位,當欄位多、資料多時,很容易出現以下問題:
- 刪錯欄位名稱。
- INSERT 欄位與 VALUES 對不起來。
- UPDATE 忘了帶主鍵條件。
- 把目標資料庫沒有的欄位也一起帶過去。
用 DBeaver 先整理欄位,再產生 SQL
我後來覺得最省力的做法,是先在 DBeaver 把要看的欄位縮到最小,再做 SQL Generation。
相關功能可參考:
實務流程
- 先查出你要同步的資料。
- 用 Data Filters 或欄位顯示設定,把不需要的欄位先隱藏。
- 確認保留下來的欄位剛好是目標資料庫也存在的欄位。
- 再從結果集產生 INSERT 或 UPDATE SQL。
這樣最大的好處是:你不是在一大串產生好的 SQL 裡面做肉眼編修,而是在結構比較清楚的表格視圖先把資料面整理乾淨。
INSERT 與 UPDATE 的注意點不一樣
產生 INSERT 時
INSERT 的重點是:
- 欄位順序與 VALUES 順序要一致。
- 目標資料庫沒有的欄位不要帶。
- 自動產生欄位、流水號欄位要先確認要不要排除。
像這樣的 SQL:
|
|
如果 id 在目標資料庫是自增欄位,這段就可能要調整。
產生 UPDATE 時
UPDATE 最容易出包的是沒帶正確條件。
例如:
|
|
我自己的習慣是:只要是產生 UPDATE,一定確認主鍵或唯一鍵條件有被帶上,不然一個不小心就可能變成整批更新。
如果 DBeaver 還是不夠用
有些情況欄位差異太大,或你需要先做 mapping、轉型、資料清洗,這時候我會考慮第二種方式:先建立臨時表,再做匯入與轉換。
流程大概是:
- 在本地或測試資料庫先建立暫存表。
- 把來源資料匯進暫存表。
- 用 SQL 明確寫出要同步到目標表的欄位。
- 最後再輸出正式要執行的 INSERT / UPDATE。
這種做法雖然步驟比較多,但好處是:
- 欄位映射比較清楚。
- 可以先做資料清洗。
- 比較適合大量資料或多欄位轉換。
什麼情況適合哪一種方法
我自己的判斷是:
- 欄位差異不大、只是想快速補資料:直接用 DBeaver。
- 欄位差異大、還要轉型或清洗:先走暫存表。
- 資料量很大、需要重複執行:考慮寫成正式 SQL script 或 ETL 流程。
補充:CSV 也是一條路
如果你拿到的是 CSV,而不是直接查資料庫,也可以先匯入再處理:
這條路特別適合來源資料不是你直接能連線的資料庫,而是別人丟給你的匯出檔。
小結
這篇的核心其實很簡單:不要把欄位刪除工作留到最後一刻的 SQL 編修階段,而是盡量往前移,在資料檢視與欄位過濾階段就處理掉。
我目前還是覺得 DBeaver 先過濾欄位、再產生 SQL,是這種臨時資料同步需求最省時間的方法。