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

如何才能做到这一点?

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


4
看来setval()至少有两个参数。

Answers:


259

括号放错了位置:

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

否则,您将setval使用单个参数进行调用,而该参数需要两个或三个。


2
最后一个参数“ true”是什么意思?
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

182

此语法在任何版本的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 '18年

1
@MitalPritmani:您可能需要强制类型转换。考虑上面添加的说明。
Erwin Brandstetter '18

1
@NuclearPeon我想你的意思是SELECT setval('sequence', (SELECT MAX(col) from table), TRUE);否则你的父母不会排队。
dland19

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个参数:

  • 第一个参数是 sequence_name
  • 第二个参数是Next nextval
  • 第三个参数是可选的。

在setval的第三个参数中使用true或false的情况如下:

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是表的名称,idprimary key


谢谢!最后的表达正是我想要的。它允许我保留顺序值以便以后批量插入。
帖木儿


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;

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.