解決 PostgresException: 23505: duplicate key value violates unique constraint

今天公司的某個舊專案遇到一個問題:某功能無法新增資料,當初開發的人員已經不在了,我看了一下錯誤訊息:
    
PostgresException: 23505: duplicate key value violates unique constraint "mytable_pkey"
    

雖然沒用過 PostgreSQL ,不過類似的錯誤訊息在其他資料庫中已經看過很多次了,無非就是只能唯一值的欄位資料重複。但是沒有找到錯誤訊息中 mytable_pkey 這個資料表,
後來意識到 mytable_pkey 代表的是 mytable 的 primary key,資料表定義範例如下:
    
create table mytable
(
    id                  serial
        primary key,
    name                varchar(30)
);
    

這個 id 是資料庫自動遞增的,程式之前也可以正常執行,依照之前的經驗判斷,有可能是取號機(自動遞增序列)的號碼錯誤,取出來的號碼和現有資料重複。

查詢資料庫 mytable 資料表的 id 欄位的自動遞增序列名稱:
    
SELECT pg_get_serial_sequence('mytable', 'id');
+----------------------+
|pg_get_serial_sequence|
+----------------------+
|public.mytable_id_seq |
+----------------------+
    

查詢 mytable_id_seq 自動遞增序列的下一個號碼:
    
SELECT last_value FROM mytable_id_seq;
+----------+
|last_value|
+----------+
|    79000 |
+----------+
    

查詢 mytable 資料表最新的 id :
    
SELECT MAX(id) FROM mytable
+----------+
|       id |
+----------+
|    79420 |
+----------+
    

依照上面的範例發現取號機的數字比實際還小,下一個號碼會取得 79,000,但在資料庫中號碼已經到 79,420 ,應該要設定為 79,421 才正確,並且目前已經遇到錯誤代表 79,000 這個 id 已經存在。 很有可能是資料還原或是關閉 id 自動產生然後插入資料。

要解決也很簡單,更新取號機的號碼至最新的 id 再 +1 就好了:
    
SELECT setval('mytable_id_seq', (SELECT MAX(id) FROM mytable) + 1);
    

留言