PostgreSQL使用一个查询增加表的序列

时间:2014-07-15 10:38:14

标签: sql postgresql sequence auto-increment

我想将以下两个查询合并为一个:

SELECT pg_get_serial_sequence('purchase_orders', 'id');
SELECT setval('purchase_orders_id_seq', 30000);

但是如果我将上面的SELECT放入setval的第一个参数中,我得到:

SELECT setval(SELECT pg_get_serial_sequence('purchase_orders', 'id'), 30000);

ERROR: syntax error at or near "SELECT"
SQL state: 42601
Character: 15

如何为setval传递select的结果(“purchase_orders_id_seq”)?

编辑:原因是:我想像一个函数一样使用它,用户只需要输入表的名称和一个数字来设置序列。

FUNCTION set_id_sequence(TEXT table_name, INTEGER sequence);

3 个答案:

答案 0 :(得分:4)

如果要将子查询结果作为函数参数传递,则需要括号括起来:

SELECT setval((SELECT pg_get_serial_sequence('purchase_orders', 'id')), 30000);

但在这种情况下,SELECT是多余的;你可以直接调用这个函数:

SELECT setval(pg_get_serial_sequence('purchase_orders', 'id'), 30000);

答案 1 :(得分:1)

一般功能和自动化

所有“迁移”或“启动数据库”SQL脚本文件在使用INSERT自动化之前都有一些受控serial序列,所以它需要一个简单的命令来说“好,回到标准操作”

这个通用操作是SELECT MAX(id)+1 FROM schemaName.tableName ... 并且,正如@NickBarnes所示,基本setval()操作是setval(pg_get_serial_sequence('schemaName.tableName', 'idName'), NEWVAL),因此将所有操作放在一起我们会自动完成任务。

2018年的标准化提案

CREATE FUNCTION std_setmaxval(
    p_tname text,
    p_id_name text DEFAULT 'id'
) RETURNS SETOF bigint AS $f$
BEGIN 
RETURN QUERY EXECUTE  format(
    'SELECT setval(pg_get_serial_sequence(%L,%L), COALESCE((SELECT MAX(%s)+1 FROM %s), 1) , false)'
     ,p_tname, p_id_name, p_id_name, p_tname
    );
END
$f$ LANGUAGE PLpgSQL;

请参阅quotation problem/solution进行优化。 请查看此答案,这是一个Wiki(!)。并更新standard snippet proposal

PS:我不明白为什么postgreSQL没有为这个任务提供原生函数......好吧,我没有看到info's Guidesequence's Guide

答案 2 :(得分:0)

更改序列所有者:

ALTER SEQUENCE purchase_orders_id_seq OWNED BY purchase_orders.id;

设置序列值:

SELECT pg_catalog.setval('purchase_orders_id_seq', 30000, true);
ALTER TABLE ONLY purchase_orders ALTER COLUMN id SET DEFAULT
    nextval('purchase_orders_id_seq'::regclass);