Postgres手动改变序列

我试图将一个序列设置为一个特定的值。

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/functions-sequence.html

330296 次浏览

选择setval('sequence_name', sequence_value)

括号放错了:

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

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

这与SELECT setval('payments_id_seq', 21)相同

此语法在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或更高版本。

使用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

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

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

其中table_name是表的名称,id是表的primary key

我不尝试通过setval改变序列。但是使用ALTER我被告知如何正确地写序列名。这只对我有用:

  1. 使用SELECT * FROM information_schema.sequences;检查所需的序列名称

  2. < p > 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;

运行文件并保存其输出,以不包括 通常的头文件,然后运行输出。例子:< / p >

psql -Atq -f reset.sql -o temp
psql -f temp
rm temp

输出将是一组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";

这招对我很管用:

SELECT pg_catalog.setval('public.hibernate_sequence', 3, true);