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 dynamically based on the id of the content. I am able to do this using grocery crud's callback_after_upload
function.
I want a next id of the content while adding a new content. I tried to use nextval()
function, but sequence gets incremented with it. How can get the last value of the sequence without using nextval()
function?
Or is there a simple way I can do this?
If you want to select the next value from sequence object, you can use this SQL statement. If you want to select multiple next values from SQL Sequence, you have to loop calling the above SQL statement and save the "next value" got in a storage. You can loop using (while loop) or by (cursor).
NEXTVAL is a function to get the next value from a sequence. Sequence is an object which returns ever-increasing numbers, different for each call, regardless of transactions etc. Each time you call NEXTVAL , you get a different number. This is mainly used to generate surrogate primary keys for you tables.
CREATE SEQUENCE creates a new sequence number generator. This involves creating and initializing a new special single-row table with the name name . The generator will be owned by the user issuing the command. If a schema name is given then the sequence is created in the specified schema.
pg_get_serial_sequence can be used to avoid any incorrect assumptions about the sequence name. This resets the sequence in one shot: SELECT pg_catalog. setval(pg_get_serial_sequence('table_name', 'id'), (SELECT MAX(id) FROM table_name)+1);
RETURNING
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.
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:
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')
.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With