问题
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