Postgres手动改变序列

ste*_*tef 149 postgresql database-sequence

我正在尝试将序列设置为特定值.

SELECT setval('payments_id_seq'), 21, true
Run Code Online (Sandbox Code Playgroud)

这给出了一个错误:

ERROR: function setval(unknown) does not exist

使用ALTER SEQUENCE似乎也不起作用?

ALTER SEQUENCE payments_id_seq LASTVALUE 22
Run Code Online (Sandbox Code Playgroud)

如何才能做到这一点?

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

NPE*_*NPE 195

括号错位:

SELECT setval('payments_id_seq', 21, true);  # next value will be 22
Run Code Online (Sandbox Code Playgroud)

否则你setval用一个参数调用,而它需要两个或三个.

  • `true`表示下一个值将是提供的数字+ 1,在这种情况下为22.`false`表示下一个值将是提供的数字,或21.默认情况下,setval的行为就像`true`一样选择.更多细节:https://www.postgresql.org/docs/9.6/static/functions-sequence.html (10认同)
  • “select setval”语法相对于“alterequence”的一个优点是您可以在其中使用嵌套查询,例如“select max(id) from payment”。 (8认同)
  • 使用此类函数的另一个优点是运行诸如“select setval('new_id_seq', nextval('old_id_seq'), false);”之类的查询,这有助于迁移 (3认同)
  • 最后一个参数“ true”是什么意思? (2认同)

Erw*_*ter 161

此语法在任何版本的PostgreSQL中无效:

ALTER SEQUENCE payments_id_seq LASTVALUE 22
Run Code Online (Sandbox Code Playgroud)

这可行:

ALTER SEQUENCE payments_id_seq RESTART WITH 22;
Run Code Online (Sandbox Code Playgroud)

并相当于:

SELECT setval('payments_id_seq', 22, FALSE);
Run Code Online (Sandbox Code Playgroud)

更多当前手册ALTER SEQUENCE序列功能.

请注意,setval()期望(regclass, bigint)或者(regclass, bigint, boolean).在上面的例子中,我提供了无类型的文字.这也有效.但是,如果将类型变量提供给函数,则可能需要显式类型转换以满足函数类型解析.喜欢:

SELECT setval(my_text_variable::regclass, my_other_variable::bigint, FALSE);
Run Code Online (Sandbox Code Playgroud)

对于您可能感兴趣的重复操作:

ALTER SEQUENCE payments_id_seq START WITH 22; -- set default
ALTER SEQUENCE payments_id_seq RESTART;       -- without value
Run Code Online (Sandbox Code Playgroud)

START [WITH]存储一个默认RESTART号码,用于RESTART没有值的后续呼叫.最后一部分需要Postgres 8.4或更高版本.

  • @dland:旁白:更短更快的等效项:`SELECT setval('seq', max(col)) FROM tbl;` 请参阅:/sf/answers/1637327961/ (5认同)
  • ``ALTER SEQUENCE [序列]重新启动(来自表的SELECT MAX(col));`不起作用,而SELECT SETval('sequence',(SELECT(来自表的MAX(col)),TRUE);`起作用。我收到语法错误(Postgres 9.4) (3认同)
  • DDL 命令(“实用程序命令”)中不允许有子查询。请参阅:/sf/answers/2521817441/ (2认同)
  • @NuclearPeon我认为你的意思是`SELECT setval('sequence', (SELECT MAX(col) from table), TRUE);`,否则你的括号不会对齐。 (2认同)

Vai*_*sVB 24

使用 select setval('payments_id_seq', 21, true);

setval 包含3个参数:

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

在setval的第3个参数中使用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
Run Code Online (Sandbox Code Playgroud)

避免序列名,下一个序列值的硬编码和正确处理空列表的更好方法,您可以使用以下方式:

SELECT setval(pg_get_serial_sequence('table_name', 'id'), coalesce(max(id), 0)+1 , false) FROM table_name;
Run Code Online (Sandbox Code Playgroud)

这里table_name是表的名称,idprimary key

  • 谢谢!最后一个表达正是我要找的。它允许我保留序列值,以便之后批量插入。 (2认同)

And*_*bak 8

setval('sequence_name', sequence_value)
Run Code Online (Sandbox Code Playgroud)


ala*_*tar 6

我不尝试通过更改顺序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;

wiki.postgresql.org上还有一个页面,其中描述了一种生成 sql 脚本以同时修复所有数据库表中的序列的方法。下面是链接中的文字:

将其保存到文件中,例如“reset.sql”

SELECT 'SELECT SETVAL(' ||
       quote_literal(quote_ident(PGT.schemaname) || '.' || quote_ident(S.relname)) ||
       ', COALESCE(MAX(' ||quote_ident(C.attname)|| '), 1) ) FROM ' ||
       quote_ident(PGT.schemaname)|| '.'||quote_ident(T.relname)|| ';'
FROM pg_class AS S,
     pg_depend AS D,
     pg_class AS T,
     pg_attribute AS C,
     pg_tables AS PGT
WHERE S.relkind = 'S'
    AND S.oid = D.objid
    AND D.refobjid = T.oid
    AND D.refobjid = C.attrelid
    AND D.refobjsubid = C.attnum
    AND T.relname = PGT.tablename
ORDER BY S.relname;
Run Code Online (Sandbox Code Playgroud)

运行该文件并以不包含常用标头的方式保存其输出,然后运行该输出。例子:

psql -Atq -f reset.sql -o temp
psql -f temp
rm temp
Run Code Online (Sandbox Code Playgroud)

输出将是一组 sql 命令,如下所示:

SELECT SETVAL('public."SocialMentionEvents_Id_seq"', COALESCE(MAX("Id"), 1) ) FROM public."SocialMentionEvents";
SELECT SETVAL('public."Users_Id_seq"', COALESCE(MAX("Id"), 1) ) FROM public."Users";
Run Code Online (Sandbox Code Playgroud)