今天公司的某個舊專案遇到一個問題:某功能無法新增資料,當初開發的人員已經不在了,我看了一下錯誤訊息:
雖然沒用過 PostgreSQL ,不過類似的錯誤訊息在其他資料庫中已經看過很多次了,無非就是只能唯一值的欄位資料重複。但是沒有找到錯誤訊息中 mytable_pkey 這個資料表,
後來意識到 mytable_pkey 代表的是 mytable 的 primary key,資料表定義範例如下:
這個 id 是資料庫自動遞增的,程式之前也可以正常執行,依照之前的經驗判斷,有可能是取號機(自動遞增序列)的號碼錯誤,取出來的號碼和現有資料重複。
查詢資料庫 mytable 資料表的 id 欄位的自動遞增序列名稱:
查詢 mytable_id_seq 自動遞增序列的下一個號碼:
查詢 mytable 資料表最新的 id :
依照上面的範例發現取號機的數字比實際還小,下一個號碼會取得 79,000,但在資料庫中號碼已經到 79,420 ,應該要設定為 79,421 才正確,並且目前已經遇到錯誤代表 79,000 這個 id 已經存在。 很有可能是資料還原或是關閉 id 自動產生然後插入資料。
要解決也很簡單,更新取號機的號碼至最新的 id 再 +1 就好了:
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);
留言
張貼留言
如果有任何問題、建議、想說的話或文章題目推薦,都歡迎留言或來信: a@ruyut.com