我想将以下两个查询合并为一个:
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);
答案 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)
,因此将所有操作放在一起我们会自动完成任务。
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 Guide或sequence'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);