Postgres แก้ไขลำดับด้วยตนเอง


189

ฉันพยายามที่จะกำหนดลำดับเป็นค่าเฉพาะ

SELECT setval('payments_id_seq'), 21, true

สิ่งนี้ทำให้เกิดข้อผิดพลาด:

ERROR: function setval(unknown) does not exist

ALTER SEQUENCEดูเหมือนว่าการใช้งานจะไม่ทำงานเช่นกันใช่ไหม

ALTER SEQUENCE payments_id_seq LASTVALUE 22

สิ่งนี้สามารถทำได้?

Ref: https://www.postgresql.org/docs/current/static/functions-sequence.html


4
ดูเหมือนว่าsetval()จะมีข้อโต้แย้งอย่างน้อยสองข้อ

คำตอบ:


262

วงเล็บถูกใส่ผิดที่:

SELECT setval('payments_id_seq', 21, true);  # next value will be 22

มิฉะนั้นคุณจะโทรหาsetvalด้วยอาร์กิวเมนต์เดียวในขณะที่มันต้องมีสองหรือสาม


2
อาร์กิวเมนต์สุดท้าย "ความจริง" หมายถึงอะไร?
inafalcao

15
trueหมายความว่าค่าถัดไปจะเป็นตัวเลขที่ให้ + 1 ในกรณีนี้ 22. falseหมายความว่าค่าถัดไปจะเป็นหมายเลขที่ให้ไว้หรือ 21 โดยค่าเริ่มต้น setval จะทำงานเหมือนtrueถูกเลือก รายละเอียดเพิ่มเติม: postgresql.org/docs/9.6/static/functions-sequence.html
Tom Mertz

1
ประโยชน์จากการที่select setvalไวยากรณ์กว่าคือการที่คุณสามารถใช้คำสั่งที่ซ้อนกันอยู่ในนั้นเช่นการalter sequence select max(id) from payments
mariotomo

187

ไวยากรณ์นี้ไม่ถูกต้องในPostgreSQL รุ่นใด ๆ :

ALTER SEQUENCE payments_id_seq LASTVALUE 22

สิ่งนี้จะได้ผล:

ALTER SEQUENCE payments_id_seq RESTART WITH 22;

และเทียบเท่ากับ:

SELECT setval('payments_id_seq', 22, FALSE);

มากขึ้นในปัจจุบันด้วยตนเองสำหรับการALTER SEQUENCEและฟังก์ชั่นลำดับ

โปรดทราบว่าsetval()คาดว่าอย่างใดอย่างหนึ่งหรือ(regclass, bigint) (regclass, bigint, boolean)ในตัวอย่างข้างต้นฉันกำลังจัดหาตัวอักษรที่ไม่ได้พิมพ์ มันก็ใช้ได้เหมือนกัน แต่ถ้าคุณป้อนตัวแปรที่พิมพ์ลงในฟังก์ชั่นคุณอาจต้องใช้การพิมพ์แบบชัดแจ้งเพื่อตอบสนองการจำแนกประเภทฟังก์ชั่น ชอบ:

SELECT setval(my_text_variable::regclass, my_other_variable::bigint, FALSE);

สำหรับการดำเนินการซ้ำคุณอาจสนใจ:

ALTER SEQUENCE payments_id_seq START WITH 22; -- set default
ALTER SEQUENCE payments_id_seq RESTART;       -- without value

START [WITH]เก็บRESTARTหมายเลขเริ่มต้นซึ่งใช้สำหรับการRESTARTโทรครั้งต่อไปโดยไม่มีค่า คุณต้องการ Postgres 8.4 หรือใหม่กว่าสำหรับส่วนสุดท้าย


4
ALTER SEQUENCE [sequence] RESTART WITH (SELECT MAX(col) from table);ไม่ทำงานในขณะที่SELECT setval('sequence', (SELECT (MAX(col) from table), TRUE);ทำงาน ฉันได้รับข้อผิดพลาดทางไวยากรณ์ (Postgres 9.4)
NuclearPeon

1
ไม่อนุญาตให้ใช้แบบสอบถามย่อยในคำสั่ง DDL ("คำสั่งยูทิลิตี้") ดู: stackoverflow.com/a/36025963/939860
Erwin Brandstetter

1
@MitalPritmani: คุณอาจต้องพิมพ์บรรยากาศ พิจารณาคำแนะนำเพิ่มเติมด้านบน
Erwin Brandstetter

1
@NuclearPeon ฉันคิดว่าคุณหมายความว่าSELECT setval('sequence', (SELECT MAX(col) from table), TRUE);อย่างอื่น parens ของคุณไม่เข้าแถว
dland

1
@dland: ข้าง: สั้นกว่าและเร็วกว่า: SELECT setval('seq', max(col)) FROM tbl;ดู: stackoverflow.com/a/23390399/939860
Erwin Brandstetter

33

ใช้ select setval('payments_id_seq', 21, true);

setval มี 3 พารามิเตอร์:

  • พารามิเตอร์ที่ 1 คือ sequence_name
  • พารามิเตอร์ที่สองคือถัดไป nextval
  • พารามิเตอร์ที่ 3 เป็นทางเลือก

การใช้ true หรือ false ในพารามิเตอร์ที่ 3 ของ setval มีดังนี้:

SELECT setval('payments_id_seq', 21);           // Next nextval will return 22
SELECT setval('payments_id_seq', 21, true);     // Same as above 
SELECT setval('payments_id_seq', 21, false);    // Next nextval will return 21

วิธีที่ดีกว่าในการหลีกเลี่ยงการเข้ารหัสอย่างหนักของชื่อลำดับค่าลำดับถัดไปและเพื่อจัดการกับตารางคอลัมน์ที่ว่างเปล่าอย่างถูกต้องคุณสามารถใช้วิธีด้านล่าง:

SELECT setval(pg_get_serial_sequence('table_name', 'id'), coalesce(max(id), 0)+1 , false) FROM table_name;

ที่table_nameเป็นชื่อของตารางidเป็นprimary keyของตาราง


ขอบคุณ! การแสดงออกครั้งสุดท้ายเป็นสิ่งที่ฉันกำลังมองหา ช่วยให้ฉันสามารถจองค่าลำดับเพื่อแทรกตามแบทช์ในภายหลัง
Timur


0

setvalผมไม่ได้ลองเปลี่ยนลำดับผ่าน แต่การใช้ALTERฉันถูกออกวิธีการเขียนชื่อลำดับอย่างถูกต้อง และนี่ใช้ได้สำหรับฉันเท่านั้น:

  1. ตรวจสอบชื่อลำดับที่ต้องการโดยใช้ SELECT * FROM information_schema.sequences;

  2. ALTER SEQUENCE public."table_name_Id_seq" restart {number};

    ในกรณีของฉันมันเป็น ALTER SEQUENCE public."Services_Id_seq" restart 8;

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.