Postgres thay đổi trình tự thủ công


189

Tôi đang cố gắng thiết lập một chuỗi thành một giá trị cụ thể.

SELECT setval('payments_id_seq'), 21, true

Điều này đưa ra một lỗi:

ERROR: function setval(unknown) does not exist

Sử dụng ALTER SEQUENCEdường như không hoạt động?

ALTER SEQUENCE payments_id_seq LASTVALUE 22

Điều này có thể giải quyết như thế nào?

Tham chiếu: https://www.postgresql.org/docs/cản/static/fifts- resultence.html


4
Nó sẽ xuất hiện setval()có ít nhất hai đối số.

Câu trả lời:


259

Các dấu ngoặc được đặt sai vị trí:

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

Nếu không, bạn đang gọi setvalvới một đối số duy nhất, trong khi nó yêu cầu hai hoặc ba.


2
Đối số cuối cùng "đúng" nghĩa là gì?
inafalcao

15
truecó nghĩa là giá trị tiếp theo sẽ là số được cung cấp + 1, trong trường hợp này 22. falsecó nghĩa là giá trị tiếp theo sẽ là số được cung cấp hoặc 21. Theo mặc định, setval sẽ hoạt động như thể trueđược chọn. Thêm chi tiết: postgresql.org/docs/9.6/static/fifts- resultence.html
Tom Mertz

1
một lợi thế của select setvalcú pháp hơn alter sequencelà bạn có thể sử dụng các truy vấn lồng nhau trong đó, ví dụ như select max(id) from payments.
mariotomo

182

Cú pháp này không hợp lệ trong bất kỳ phiên bản nào của PostgreSQL:

ALTER SEQUENCE payments_id_seq LASTVALUE 22

Điều này sẽ làm việc:

ALTER SEQUENCE payments_id_seq RESTART WITH 22;

và tương đương với:

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

Thêm trong hướng dẫn hiện tại cho ALTER SEQUENCEchức năng trình tự .

Lưu ý rằng setval()mong đợi (regclass, bigint)hoặc (regclass, bigint, boolean). Trong ví dụ trên tôi đang cung cấp những chữ chưa được chỉnh sửa . Điều đó cũng làm việc. Nhưng nếu bạn cung cấp các biến được nhập cho hàm, bạn có thể cần các kiểu phôi rõ ràng để đáp ứng độ phân giải của hàm. Giống:

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

Đối với các hoạt động lặp đi lặp lại, bạn có thể quan tâm:

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

START [WITH]lưu trữ một RESTARTsố mặc định , được sử dụng cho các RESTARTcuộc gọi tiếp theo mà không có giá trị. Bạn cần Postgres 8.4 trở lên cho phần cuối cùng.


4
ALTER SEQUENCE [sequence] RESTART WITH (SELECT MAX(col) from table);không hoạt động, trong khi SELECT setval('sequence', (SELECT (MAX(col) from table), TRUE);không hoạt động. Tôi nhận được một lỗi cú pháp. (Postgres 9.4)
NuclePeon

1
Không có truy vấn con nào được phép trong lệnh DDL ("lệnh tiện ích"). Xem: stackoverflow.com/a/36025963/939860
Erwin Brandstetter

1
@MitalPritmani: Bạn có thể cần loại phôi. Xem xét hướng dẫn thêm ở trên.
Erwin Brandstetter

1
@NuclePeon Tôi nghĩ bạn có nghĩa là SELECT setval('sequence', (SELECT MAX(col) from table), TRUE);nếu không thì parens của bạn không xếp hàng.
dland

1
@dland: Ngoài ra: tương đương ngắn hơn & nhanh hơn: SELECT setval('seq', max(col)) FROM tbl;Xem: stackoverflow.com/a/23390399/939860
Erwin Brandstetter

33

Sử dụng select setval('payments_id_seq', 21, true);

setval chứa 3 tham số:

  • Tham số 1 là sequence_name
  • Tham số thứ 2 là Tiếp theo nextval
  • Tham số thứ 3 là tùy chọn.

Việc sử dụng đúng hoặc sai trong tham số thứ 3 của setval như sau:

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

Cách tốt hơn để tránh mã hóa cứng tên chuỗi, giá trị chuỗi tiếp theo và để xử lý chính xác bảng cột trống, bạn có thể sử dụng cách dưới đây:

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

nơi table_namelà tên của bảng, idprimary keycủa bảng


Cảm ơn bạn! Biểu hiện cuối cùng là chính xác những gì tôi đang tìm kiếm. Nó cho phép tôi dự trữ các giá trị chuỗi để chèn theo đợt sau đó.
Timur


0

Tôi không thử thay đổi trình tự qua setval. Nhưng sử dụng ALTERtôi đã được ban hành làm thế nào để viết tên trình tự đúng. Và điều này chỉ làm việc cho tôi:

  1. Kiểm tra tên trình tự được yêu cầu bằng cách sử dụng SELECT * FROM information_schema.sequences;

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

    Trong trường hợp của tôi, nó là ALTER SEQUENCE public."Services_Id_seq" restart 8;

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.