Select multiple ids from a PostgreSQL sequence

后端 未结 5 2021
广开言路
广开言路 2021-01-01 11:54

Is there a concise way to select the nextval for a PostgreSQL sequence multiple times in 1 query? This would be the only value being returned.

For example, I would

相关标签:
5条回答
  • 2021-01-01 12:08
    
    CREATE OR REPLACE FUNCTION foo() RETURNS SETOF INT AS $$
    DECLARE
        seqval int; x int;
    BEGIN
    x := 0;
    
    WHILE x < 100 LOOP
        SELECT into seqval nextval('f_id_seq');
        RETURN NEXT seqval;
        x := x+1;
    END LOOP;
    RETURN;
    END;
    $$ LANGUAGE plpgsql STRICT;
    

    Of course, if all you're trying to do is advance the sequence, there's setval().

    You could also have the function take a parameter for how many times to loop:

    CREATE OR REPLACE FUNCTION foo(loopcnt int) RETURNS SETOF INT AS $$
    DECLARE
        seqval int;       
        x int;
    BEGIN
    x := 0;
    WHILE x < loopcnt LOOP
        SELECT into seqval nextval('f_id_seq');
        RETURN NEXT seqval;x := x+1;
    END LOOP;
    RETURN;
    END;
    $$ LANGUAGE plpgsql STRICT;
    
    0 讨论(0)
  • 2021-01-01 12:12

    My current best solution is:

    SELECT NEXTVAL('mytable_seq') AS id
    UNION ALL
    SELECT NEXTVAL('mytable_seq') AS id
    UNION ALL
    SELECT NEXTVAL('mytable_seq') AS id;
    

    Which will correctly return 3 rows... but I would like something that is minimal SQL for even as much as 100 or more NEXTVAL invocations.

    0 讨论(0)
  • 2021-01-01 12:16

    There is a great article about this exact problem: "getting multiple values from sequences".

    If performance is not an issue, for instance when using the sequence values dwarfs the time used to get them or n is small, then the SELECT nextval('seq') FROM generate_series(1,n) approach is the simplest and most appropriate.

    But when preparing data for bulk loads the last approach from the article of incrementing the sequence by n from within a lock is appropriate.

    0 讨论(0)
  • 2021-01-01 12:21

    Unless you really want three rows returned I would set the sequence to 'INCREMENT BY 3' for each select. Then you can simple add 1 and 2 to the result have have your three sequence numbers.

    I tried to add a link to the postgresql docs, but apparenty I am not allowed to post links.

    0 讨论(0)
  • 2021-01-01 12:24
    select nextval('mytable_seq') from generate_series(1,3);
    

    generate_series is a function which returns many rows with sequential numbers, configured by it's arguments.

    In above example, we don't care about the value in each row, we just use generate_series as row generator. And for each row we can call nextval. In this case it returns 3 numbers (nextvals).

    You can wrap this into function, but I'm not sure if it's really sensible given how short the query is.

    0 讨论(0)
提交回复
热议问题