CodeGym /課程 /SQL SELF /批量匯入資料時常見的錯誤

批量匯入資料時常見的錯誤

SQL SELF
等級 24, 課堂 4
開放

在 PostgreSQL 裡批量匯入資料就像在玩俄羅斯方塊:每個小方塊(資料)都要剛好塞進現有的表格(資料庫結構)裡。但就像打電動一樣,常常會出現各種錯誤,可能會拖慢進度,甚至直接 GG。你可能會遇到資料型別不符、編碼問題、重複資料,甚至還有權限相關的奇怪錯誤。

到底會有哪些錯誤?怎麼發現、怎麼避免?今天我們就來細聊這些最常見的問題,讓你也能變成批量匯入資料的高手!

資料結構不符的錯誤

資料型別的問題

很常在匯入資料時你會看到像這樣的錯誤:

ERROR:  輸入語法無效,預期型別 integer: "abc"
CONTEXT:  COPY 學生, 第3行, 欄位 年齡: "abc"

這種情況通常是你的 CSV 檔案裡的資料型別跟資料表預期的不一樣。比如 age 欄位本來要數字,結果資料裡卻是 "abc" 這種字串。PostgreSQL 不知道怎麼把文字轉成數字,匯入就直接中斷了。

怎麼避免?

  1. 匯入前先檢查你的 CSV 檔案。如果你用 Excel 或 Python 處理,記得每個欄位都要對應正確的型別。
  2. 如果還是有錯,可以先把資料匯到一個所有欄位都是 TEXT 的暫存表,然後再轉型別:
UPDATE temp_students
SET age = CAST(age AS INTEGER)
WHERE age ~ '^\d+$';

缺少欄位

如果資料表的結構跟 CSV 檔案不一樣,PostgreSQL 會報錯。例如:

ERROR:  欄位 "email" 缺少資料
CONTEXT:  COPY 學生, 第2行: "John,Doe,21"

這通常是因為 CSV 檔案的標題(或欄位順序)跟資料表不一樣。

怎麼避免? 用 COPY 指令時,記得指定你要填的欄位:

COPY students (first_name, last_name, age)
FROM '/path/to/file.csv' 
DELIMITER ',' 
CSV HEADER;

編碼錯誤

不同編碼的問題

如果你的 CSV 檔案不是用 UTF-8 存的(比如 Windows-1251),PostgreSQL 可能會看不懂,尤其裡面有俄文或其他特殊字元時會直接報錯:

ERROR:  編碼 "UTF8" 的位元組序列無效: 0xd0
CONTEXT:  COPY 學生, 第1行

怎麼避免?

  1. 確認你的 CSV 檔案是用 UTF-8 編碼。
  2. 如果真的沒辦法,匯入時指定檔案的編碼:
COPY students FROM '/path/to/file.csv'
DELIMITER ',' 
CSV HEADER 
ENCODING 'WIN1251';

檔案存取權限錯誤

權限不足的問題

用 COPY 指令時,PostgreSQL 必須能存取你要匯入的檔案。如果檔案沒權限,會看到這種錯誤:

ERROR:  無法開啟檔案 "/path/to/file.csv" 讀取: 權限被拒絕

或甚至:

ERROR:  找不到檔案或目錄

怎麼避免?

  1. 確認 PostgreSQL 有權限存取檔案。在 Linux 下通常是權限問題。用 chmod 指令開權限:
    chmod 644 /path/to/file.csv
    
  2. 如果你是在自己電腦上操作,用 \COPY,不要用 COPY。

重複資料的問題

如果你要匯入的資料表有 UNIQUE 限制(像是唯一識別碼),遇到重複資料就會報錯:

ERROR:  重複的鍵值違反唯一限制 "students_pkey"
DETAIL:  鍵 (id)=(1) 已經存在。

這通常是 CSV 檔案裡有重複資料,或資料表裡已經有這些資料了。

怎麼避免?

  1. 用 ON CONFLICT 處理重複值:
    INSERT INTO students (id, first_name, last_name)
    VALUES (1, 'John', 'Doe')
    ON CONFLICT (id) DO NOTHING;
    
  1. 如果你用 COPY 或 \COPY,可以先匯到暫存表,再處理重複資料後插入主表。

空值錯誤

在 PostgreSQL 裡,設了 NOT NULL 限制的欄位不能有空值。如果你的 CSV 檔案有空欄位,會看到這種錯誤:

ERROR:  欄位 "email" 的值為 null 違反 not-null 限制

怎麼避免?

  1. 確認 CSV 檔案裡所有必填欄位都有值。
  2. 如果允許空值,可以移除 NOT NULL 限制,或設個預設值:
ALTER TABLE students ALTER COLUMN email SET DEFAULT 'unknown@example.com';

日誌記錄錯誤

沒有錯誤資訊

如果你在匯入大檔案,記錄錯誤資訊很重要。可惜 COPY 預設沒提供錯誤日誌的功能。

怎麼避免? 可以自己設一個錯誤日誌表,把有問題的資料丟進去:

COPY students FROM '/path/to/file.csv'
DELIMITER ',' 
CSV HEADER
LOG ERRORS INTO error_log
REJECT LIMIT 100;

避免錯誤的總結

  1. 匯入前一定要先分析、檢查資料。
  2. 用暫存表先處理資料再正式匯入。
  3. 開啟錯誤日誌,記得檢查錯誤。
  4. 遇到衝突或不符時,用 ON CONFLICT 或暫存表處理。
  5. 檢查檔案編碼,設定好伺服器參數。

批量匯入資料其實不簡單,但只要方法對,這流程就會又快又穩又有效率。想試試你的新技能嗎?找個大一點的 CSV 檔案,丟進測試資料庫,看看資料是不是都正確進去了!

2
任務
SQL SELF, 等級 24, 課堂 4
上鎖
解決重複記錄的問題
解決重複記錄的問題
1
問卷/小測驗
大量匯入優化,等級 24,課堂 4
未開放
大量匯入優化
大量匯入優化
留言
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION