Di PostgreSQL, bagaimana cara saya mendapatkan id terakhir dimasukkan ke dalam tabel?
Dalam MS SQL ada SCOPE_IDENTITY ().
Tolong jangan menyarankan saya untuk menggunakan sesuatu seperti ini:
select max(id) from table
postgresql
insert
lastinsertid
Anton
sumber
sumber
Jawaban:
(
tl;dr
: opsi goto 3: INSERT dengan RETURNING)Ingatlah bahwa dalam postgresql tidak ada konsep "id" untuk tabel, hanya urutan (yang biasanya tetapi tidak selalu digunakan sebagai nilai default untuk kunci utama pengganti, dengan SERIAL pseudo-type).
Jika Anda tertarik untuk mendapatkan id dari baris yang baru dimasukkan, ada beberapa cara:
Pilihan 1:
CURRVAL(<sequence name>);
.Sebagai contoh:
Nama urutan harus diketahui, itu benar-benar sewenang-wenang; dalam contoh ini kita mengasumsikan bahwa tabel
persons
memilikiid
kolom yang dibuat dengan tipeSERIAL
pseudo. Untuk menghindari mengandalkan ini dan merasa lebih bersih, Anda bisa menggunakanpg_get_serial_sequence
:Peringatan:
currval()
hanya berfungsi setelahINSERT
(yang telah dieksekusinextval()
), di sesi yang sama .Pilihan 2:
LASTVAL();
Ini mirip dengan yang sebelumnya, hanya saja Anda tidak perlu menentukan nama urutan: mencari urutan modifikasi terbaru (selalu di dalam sesi Anda, peringatan yang sama seperti di atas).
Keduanya
CURRVAL
danLASTVAL
aman secara bersamaan. Perilaku urutan dalam PG dirancang sehingga sesi yang berbeda tidak akan mengganggu, sehingga tidak ada risiko kondisi balapan (jika sesi lain menyisipkan baris lain antara INSERT dan SELECT saya, saya masih mendapatkan nilai yang benar).Namun mereka memiliki masalah potensial yang tidak kentara. Jika database memiliki beberapa TRIGGER (atau ATURAN) yang, pada saat dimasukkan ke dalam
persons
tabel, membuat beberapa tambahan di tabel lain ... makaLASTVAL
mungkin akan memberi kita nilai yang salah. Masalahnya bahkan dapat terjadi denganCURRVAL
, jika penyisipan tambahan dilakukan kepersons
tabel yang sama (ini jauh lebih jarang, tetapi risikonya masih ada).Opsi 3:
INSERT
denganRETURNING
Ini adalah cara yang paling bersih, efisien dan aman untuk mendapatkan id. Itu tidak memiliki risiko seperti sebelumnya.
Kekurangannya? Hampir tidak ada: Anda mungkin perlu memodifikasi cara Anda memanggil pernyataan INSERT Anda (dalam kasus terburuk, mungkin API atau lapisan DB Anda tidak mengharapkan INSERT untuk mengembalikan nilai); itu bukan SQL standar (siapa yang peduli); ini tersedia sejak Postgresql 8.2 (Des 2006 ...)
Kesimpulan: Jika Anda bisa, pilih opsi 3. Di tempat lain, pilih 1.
Catatan: semua metode ini tidak berguna jika Anda bermaksud mendapatkan id yang dimasukkan terakhir secara global (tidak harus oleh sesi Anda). Untuk ini, Anda harus menggunakan
SELECT max(id) FROM table
(tentu saja, ini tidak akan membaca sisipan tanpa komitmen dari transaksi lain).Sebaliknya, Anda tidak boleh menggunakan
SELECT max(id) FROM table
salah satu dari 3 opsi di atas, untuk mendapatkan id yang baru saja dihasilkan olehINSERT
pernyataan Anda , karena (terlepas dari kinerja) ini tidak bersamaan aman: antara AndaINSERT
dan AndaSELECT
sesi lain mungkin telah memasukkan catatan lain.sumber
SELECT max(id)
sayangnya tidak melakukan pekerjaan itu segera setelah Anda mulai menghapus baris.1,2,3,4,5
dan menghapus baris 4 dan 5, ID yang dimasukkan terakhir masih 5, tetapimax()
mengembalikan 3.RETURNING id;
untuk memasukkan ini ke tabel lain akan diterima!RETURNING id
skrip SQL yang diumpankan kepsql
alat baris perintah?Lihat klausa KEMBALI dari pernyataan INSERT . Pada dasarnya, INSERT berfungsi ganda sebagai kueri dan mengembalikan nilai yang dimasukkan.
sumber
insert into names (firstname, lastname) values ('john', 'smith') returning id;
, maka itu hanya output id sama seperti jika Anda berlariselect id from names where id=$lastid
langsung. Jika Anda ingin menyimpan pengembalian ke variabel aa , makainsert into names (firstname, lastname) values ('john', 'smith') returning id into other_variable;
Jika pernyataan yang berisi pengembalian adalah pernyataan terakhir dalam suatu fungsi , maka id yang sedangreturning
dikembalikan oleh fungsi secara keseluruhan.Anda dapat menggunakan klausa RETURNING dalam pernyataan INSERT, seperti berikut ini
sumber
Jawaban Leonbloy cukup lengkap. Saya hanya akan menambahkan kasus khusus di mana orang perlu mendapatkan nilai yang dimasukkan terakhir dari dalam fungsi PL / pgSQL di mana OPSI 3 tidak cocok persis.
Misalnya, jika kita memiliki tabel berikut:
Jika kita perlu memasukkan catatan klien, kita harus merujuk ke catatan orang. Tetapi katakanlah kita ingin merancang fungsi PL / pgSQL yang menyisipkan catatan baru ke klien tetapi juga menangani memasukkan catatan orang baru. Untuk itu, kita harus menggunakan sedikit variasi dari OPSI leonbloy's 3:
Perhatikan bahwa ada dua klausa INTO. Oleh karena itu, fungsi PL / pgSQL akan didefinisikan seperti:
Sekarang kita bisa memasukkan data baru menggunakan:
atau
Dan kami mendapatkan id yang baru dibuat.
sumber
Untuk yang perlu mendapatkan semua catatan data, Anda dapat menambahkan
ke akhir kueri Anda untuk mendapatkan semua objek termasuk id.
sumber
Lihat contoh di bawah ini
Kemudian untuk mendapatkan id yang dimasukkan terakhir gunakan ini untuk tabel "user" seq nama kolom "id"
sumber
Anda harus memberikan nama tabel dan nama kolom tentu saja.
Ini akan untuk sesi / koneksi saat ini http://www.postgresql.org/docs/8.3/static/functions-afterence.html
sumber
Coba ini:
Jika ini mengembalikan 1 (atau apa pun yang merupakan nilai start_untuk urutan Anda), maka setel ulang urutan kembali ke nilai asli, dengan melewati panji palsu:
Jika tidak,
Ini akan mengembalikan nilai urutan ke keadaan semula dan "setval" akan kembali dengan nilai urutan yang Anda cari.
sumber
Postgres memiliki mekanisme inbuilt untuk hal yang sama, yang dalam kueri yang sama mengembalikan id atau apa pun yang Anda inginkan kueri kembali. ini sebuah contoh. Pertimbangkan Anda memiliki tabel yang dibuat yang memiliki 2 kolom column1 dan column2 dan Anda ingin agar kolom1 dikembalikan setelah setiap sisipan.
sumber
Saya punya masalah dengan Java dan Postgres. Saya memperbaikinya dengan memperbarui versi Connector-J baru.
postgresql-9.2-1002.jdbc4.jar
https://jdbc.postgresql.org/download.html : Versi 42.2.12
https://jdbc.postgresql.org/download/postgresql-42.2.12.jar
sumber