چطور در PostgreSQL مقدار خودکار ستون کلید اصلی را ریست کنیم؟
وقتی با این مشکل مواجه میشوید که دنباله کلید اولیه در PostgreSQL با رکوردهای جدول همخوانی ندارد و در هنگام درج رکورد جدید با خطای کلید تکراری روبرو میشوید. ابتدا باید حداکثر مقدار کلید را در جدول خود پیدا کنید تا معلوم شود آخرین مقدار دنباله چیست. این کار را با اجرای دستور زیر می توانید انجام دهید:
SELECT MAX(id) FROM your_table;
سپس، باید مقدار بعدی دنباله را چک کنید:
SELECT nextval('your_table_id_seq');
اگر مقدار به دست آمده از nextval کمتر یا برابر با حداکثر مقدار کلید در جدول بود، میتوانید با استفاده از کد زیر آن را به روز کنید:
BEGIN;
LOCK TABLE table_name IN EXCLUSIVE MODE;
SELECT setval('table_name_id_seq', (SELECT GREATEST(MAX(id), nextval('table_name_id_seq')-1) FROM table_name));
COMMIT;
به جای پیدا کردن نام دنباله 'your_table_id_seq' در دیتابیس، میتوانید از تابع pg_get_serial_sequence استفاده کنید:
SELECT pg_catalog.setval(pg_get_serial_sequence('table_name', 'id'), (SELECT MAX(id) FROM table_name) + 1);
یا حتی کوتاهتر:
SELECT pg_catalog.setval(pg_get_serial_sequence('table_name', 'id'), MAX(id)) FROM table_name;
در صورتی که جدول شما خالی باشد، باید به شکلی عمل کنید که دنباله به درستی تنظیم شود. از آنجایی که در حالت خالی دنباله نمیتواند setval را با مقدار صفر مقدار دهی کند، میتوانید از دستور زیر استفاده کنید:
SELECT setval(pg_get_serial_sequence('t1', 'id'), COALESCE(MAX(id), 0) + 1, false) FROM t1;
دقت داشته باشید که استفاده از lock در حین بهروز کردن دنبالهها میتواند از بروز مشکلات همزمانی جلوگیری کند.
در نهایت، با توجه به اینکه وجود فاصلهها در دنبالهها عادی است و میتواند به دلایل مختلفی مانند برگشت تراکنشها یا خاموشی ناگهانی سرور ایجاد شود، برای مشکلات احتمالی در کد اپلیکیشن خود آماده باشید. اگر اپلیکیشن شما نمیتواند این گونه شکافها هندل کند، بهتر است این مورد را در برنامه خود بهبود دهید.