PostgreSQL next value of the sequences?

后端 未结 7 1654
天命终不由人
天命终不由人 2020-12-01 14:20

I am using PostgreSQL for my Codeigniter website. I am using grocery crud for add, edit and delete operations. While doing an edit or add, I want to rename an uploaded file

相关标签:
7条回答
  • 2020-12-01 14:20

    If your are not in a session you can just nextval('you_sequence_name') and it's just fine.

    0 讨论(0)
  • 2020-12-01 14:22

    Even if this can somehow be done it is a terrible idea since it would be possible to get a sequence that then gets used by another record!

    A much better idea is to save the record and then retrieve the sequence afterwards.

    0 讨论(0)
  • 2020-12-01 14:30

    I tried this and it works perfectly

    @Entity
    public class Shipwreck {
      @Id
      @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "seq")
      @Basic(optional = false)
      @SequenceGenerator(name = "seq", sequenceName = "shipwreck_seq", allocationSize = 1)
      Long id;
    

    ....

    CREATE SEQUENCE public.shipwreck_seq
        INCREMENT 1
        START 110
        MINVALUE 1
        MAXVALUE 9223372036854775807
        CACHE 1;
    
    0 讨论(0)
  • 2020-12-01 14:32

    RETURNING

    Since PostgreSQL 8.2, that's possible with a single round-trip to the database:

    INSERT INTO tbl(filename)
    VALUES ('my_filename')
    RETURNING tbl_id;
    

    tbl_id would typically be a serial or IDENTITY (Postgres 10 or later) column. More in the manual.

    Explicitly fetch value

    If filename needs to include tbl_id (redundantly), you can still use a single query.

    Use lastval() or the more specific currval():

    INSERT INTO tbl (filename)
    VALUES ('my_filename' || currval('tbl_tbl_id_seq')   -- or lastval()
    RETURNING tbl_id;
    

    See:

    • Reference value of serial column in another column during same INSERT

    If multiple sequences may be advanced in the process (even by way of triggers or other side effects) the sure way is to use currval('tbl_tbl_id_seq').

    Name of sequence

    The string literal 'tbl_tbl_id_seq' in my example is supposed to be the actual name of the sequence and is cast to regclass, which raises an exception if no sequence of that name can be found in the current search_path.

    tbl_tbl_id_seq is the automatically generated default for a table tbl with a serial column tbl_id. But there are no guarantees. A column default can fetch values from any sequence if so defined. And if the default name is taken when creating the table, Postgres picks the next free name according to a simple algorithm.

    If you don't know the name of the sequence for a serial column, use the dedicated function pg_get_serial_sequence(). Can be done on the fly:

    INSERT INTO tbl (filename)
    VALUES ('my_filename' || currval(pg_get_serial_sequence('tbl', 'tbl_id'))
    RETURNING tbl_id;
    

    db<>fiddle here
    Old sqlfiddle

    0 讨论(0)
  • 2020-12-01 14:32

    The previously obtained value of a sequence is accessed with the currval() function.

    But that will only return a value if nextval() has been called before that.

    There is absolutely no way of "peeking" at the next value of a sequence without actually obtaining it.

    But your question is unclear. If you call nextval() before doing the insert, you can use that value in the insert. Or even better, use currval() in your insert statement:

    select nextval('my_sequence') ...
    
    ... do some stuff with the obtained value
    
    insert into my_table(id, filename)
    values (currval('my_sequence'), 'some_valid_filename');
    
    0 讨论(0)
  • 2020-12-01 14:32

    To answer your question literally, here's how to get the next value of a sequence without incrementing it:

    SELECT
     CASE WHEN is_called THEN
       last_value + 1
     ELSE
       last_value
     END
    FROM sequence_name
    

    Obviously, it is not a good idea to use this code in practice. There is no guarantee that the next row will really have this ID. However, for debugging purposes it might be interesting to know the value of a sequence without incrementing it, and this is how you can do it.

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