PostgreSQL increase a table's sequence with one query

亡梦爱人 提交于 2019-12-24 03:24:06

问题


I want to unite the following two queries into one:

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

But if I place the upper SELECT into the setval's first parameter I get:

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

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

How can I pass on the select's result ("purchase_orders_id_seq") for setval?

EDIT: The reason for this is that; I want to use it like a function where a user only have to enter the table's name and a number to where sequence will be set.

FUNCTION set_id_sequence(TEXT table_name, INTEGER sequence);

回答1:


If you want to pass a subquery result as a function argument, you need parentheses around it:

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

But in this case, the SELECT is redundant; you can invoke the function directly:

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



回答2:


General function and automation

All "migration" or "starting database" SQL-script files have some controlled INSERT sequence before to use serial automation, so it need a simple command to say "ok, back to standard operation".

This generic operation is SELECT MAX(id)+1 FROM schemaName.tableName... and, as @NickBarnes showed above, the basic setval() operation is setval(pg_get_serial_sequence('schemaName.tableName', 'idName'), NEWVAL), so putting all together we automate the task.

2018's standardization proposal

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;

See quotation problem/solution to optimize. Please review this answer, it is a Wiki (!). And update the standard snippet proposal.


PS: I not understand why postgreSQL not offer a native function for this task... Well, I not see at info's Guide or sequence's Guide.




回答3:


Change Sequence owner:

ALTER SEQUENCE purchase_orders_id_seq OWNED BY purchase_orders.id;

Set sequence value:

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);


来源:https://stackoverflow.com/questions/24756035/postgresql-increase-a-tables-sequence-with-one-query

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!