2

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);
5
  • Edit your question and add the query that is failing. Commented Jul 15, 2014 at 10:44
  • What is pg_serial_get_sequence? I've never heard of it, and my 9.4 install professes ignorance when asked with \df pg_get_serial_sequence. What're you trying to accomplish/fix here, what problem are you trying to solve? Commented Jul 15, 2014 at 11:30
  • I edited the question, maybe it's clearer now. Commented Jul 15, 2014 at 11:45
  • No, not really. Why do you need to do this in the first place? You shouldn't need to go around setting sequences. Commented Jul 15, 2014 at 16:24
  • It's not me who needs this. :) Our client has a sys-admin and he requested that he could separate default data by having their ids starting from 1 and user-created entries with an offset of let's say 10000. Commented Jul 17, 2014 at 9:34

3 Answers 3

5

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);
Sign up to request clarification or add additional context in comments.

1 Comment

YES! That's it! Thank you so much, it was a redundant SELECT. :-)
1

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.

Comments

0

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

1 Comment

It's almost there! But the SET DEFAULT will not accept pg_get_serial_sequence('purchase_orders', 'id') for the ::regclass. So who wants to modify the purchase_orders table still have to know the 'purchase_orders_id_seq' identifier. What I had in my mind was a function like: set_id_sequence(TEXT table_name, INTEGER sequence). Thus a person calling this function only have to know the table's name.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.