Saya punya meja:
CREATE TABLE names (id serial, name varchar(20))
Saya ingin "id yang terakhir disisipkan" dari tabel itu, tanpa menggunakan RETURNING id
saat disisipkan. Tampaknya ada fungsi CURRVAL()
, tetapi saya tidak mengerti bagaimana menggunakannya.
Saya sudah mencoba:
SELECT CURRVAL() AS id FROM names_id_seq
SELECT CURRVAL('names_id_seq')
SELECT CURRVAL('names_id_seq'::regclass)
tapi tidak ada yang bekerja. Bagaimana saya bisa menggunakan currval()
untuk mendapatkan id yang disisipkan terakhir?
postgresql
sequence
Jonas
sumber
sumber
currval()
pasti tidak berkecil hati.Jawaban:
Jika Anda membuat kolom sebagai
serial
PostgreSQL secara otomatis membuat urutan untuk itu.Nama urutan di-autogenerasi dan selalu tablename_columnname_seq, dalam kasus Anda urutannya adalah nama
names_id_seq
.Setelah memasukkan ke dalam tabel, Anda dapat memanggil
currval()
dengan nama urutan itu:Alih-alih meng-hardcoding nama urutan, Anda juga bisa menggunakan
pg_get_serial_sequence()
:Dengan begitu Anda tidak perlu bergantung pada strategi penamaan yang digunakan Postgres.
Atau jika Anda tidak ingin menggunakan nama urutan sama sekali, gunakan
lastval()
sumber
currval()
dalam pengaturan multi-pengguna. Misalnya di server web.currval()
"lokal" ke koneksi Anda saat ini. Jadi tidak ada masalah menggunakannya di lingkungan multi-pengguna. Itulah keseluruhan tujuan dari suatu urutan.Ini langsung dari Stack Overflow
Seperti yang ditunjukkan oleh @a_horse_with_no_name dan @Jack Douglas, currval hanya berfungsi dengan sesi saat ini. Jadi, jika Anda setuju dengan kenyataan bahwa hasilnya mungkin dipengaruhi oleh transaksi yang tidak dikomit dari sesi lain, dan Anda masih menginginkan sesuatu yang akan bekerja lintas sesi, Anda dapat menggunakan ini:
Gunakan tautan ke SO untuk informasi lebih lanjut.
Dari dokumentasi Postgres , jelas dinyatakan
Jadi saya kira benar-benar berbicara untuk menggunakan dengan benar nilai saat ini atau last_value untuk urutan di seluruh sesi, Anda perlu melakukan sesuatu seperti itu?
Dengan asumsi, tentu saja, bahwa Anda tidak akan memiliki sisipan atau cara lain untuk menggunakan bidang serial di sesi saat ini.
sumber
nextval()
Anda, maka Anda harus secara manual mengatur urutan untuk mencocokkan jumlah catatan fixture yang Anda masukkan dengan ID hardcoded. Selain itu, cara untuk memecahkan masalah currval () / lastval () tidak tersedia pra-nextval adalah dengan langsungSELECT
pada urutannya.Anda perlu memanggil
nextval
urutan ini di sesi ini sebelumcurrval
:jadi Anda tidak dapat menemukan 'id yang dimasukkan terakhir' dari urutan kecuali jika
insert
dilakukan di sesi yang sama (transaksi mungkin mundur tetapi urutannya tidak akan)seperti yang ditunjukkan dalam jawaban a_horse,
create table
dengan kolom tipeserial
akan secara otomatis membuat urutan dan menggunakannya untuk menghasilkan nilai default untuk kolom, sehinggainsert
biasanya mengaksesnextval
secara implisit:sumber
Jadi ada beberapa masalah dengan berbagai metode ini:
Currval hanya mendapatkan nilai terakhir yang dihasilkan di sesi saat ini - yang sangat bagus jika Anda tidak memiliki hal lain yang menghasilkan nilai, tetapi dalam kasus di mana Anda dapat memanggil pemicu dan / atau memiliki urutan yang ditingkatkan lebih dari sekali dalam transaksi saat ini, tidak akan mengembalikan nilai yang benar. Itu bukan masalah bagi 99% orang di luar sana - tetapi itu adalah sesuatu yang harus dipertimbangkan.
Cara terbaik untuk mendapatkan pengidentifikasi unik yang ditetapkan setelah operasi memasukkan menggunakan klausa PENGEMBALIAN. Contoh di bawah ini mengasumsikan bahwa kolom yang dikaitkan dengan urutan disebut "id":
Perhatikan bahwa kegunaan klausa RETURNING melampaui hanya mendapatkan urutan, karena juga akan:
Kembalikan nilai yang sedang dihapus:
hapus dari tabel A di mana id> 100 kembali *
Kembalikan baris yang diubah setelah PEMBARUAN:
perbarui tabel Satu set X = 'y' di mana blah = 'blech' kembali *
Gunakan hasil penghapusan untuk pembaruan:
DENGAN A sebagai (hapus * dari tabel A sebagai id kembali) pembaruan B setel dihapus = true di mana id dalam (pilih id dari A);
sumber
RETURNING
klausa - tetapi, tidak ada salahnya membuat manfaat menggunakannya lebih jelas bagi orang lain.Saya harus menjalankan kueri walaupun menggunakan SQLALchemy karena saya tidak berhasil menggunakan currval.
Ini adalah proyek python flask + postgresql.
sumber
Jika Anda ingin mendapatkan nilai urutan tanpa memanggil
nextval()
, dan tanpa harus memodifikasi urutan, saya mengumpulkan fungsi PL / pgSQL untuk menanganinya: Temukan nilai semua urutan databasesumber
Anda perlu
GRANT
menggunakan skema, seperti ini:dan
sumber
currval()
fungsi untuk membuatnya sedikit lebih relevan dengan utas ini?Dalam PostgreSQL 11.2 Anda dapat memperlakukan urutan seperti tabel, tampaknya:
Contoh jika Anda memiliki urutan bernama: 'names_id_seq'
Itu akan memberi Anda id yang dimasukkan terakhir (4 dalam hal ini) yang berarti bahwa nilai saat ini (atau nilai yang harus digunakan untuk id berikutnya) harus 5.
sumber
Versi PostgreSQL yang berbeda mungkin memiliki fungsi yang berbeda untuk mendapatkan id urutan saat ini atau selanjutnya.
Pertama, Anda harus tahu versi Postgres Anda. Menggunakan versi pilih (); untuk mendapatkan versi.
Di PostgreSQL 8.2.15, Anda mendapatkan id urutan saat ini dengan menggunakan
select last_value from schemaName.sequence_name
.Jika pernyataan di atas tidak berhasil, Anda dapat menggunakan
select currval('schemaName.sequence_name');
sumber