PostgreSQL
 sql >> Teknologi Basis Data >  >> RDS >> PostgreSQL

Fungsi PostgreSQL untuk ID yang terakhir dimasukkan

( tl;dr :goto opsi 3:INSERT with RETURNING )

Ingat bahwa di postgresql tidak ada konsep "id" untuk tabel, hanya urutan (yang biasanya tetapi tidak selalu digunakan sebagai nilai default untuk kunci primer pengganti, dengan tipe semu SERIAL).

Jika Anda tertarik untuk mendapatkan id dari baris yang baru dimasukkan, ada beberapa cara:

Opsi 1:CURRVAL(<sequence name>); .

Misalnya:

  INSERT INTO persons (lastname,firstname) VALUES ('Smith', 'John');
  SELECT currval('persons_id_seq');

Nama urutannya harus diketahui, itu benar-benar arbitrer; dalam contoh ini kita asumsikan bahwa tabel persons memiliki id kolom dibuat dengan SERIAL tipe semu. Untuk menghindari mengandalkan ini dan untuk merasa lebih bersih, Anda dapat menggunakan pg_get_serial_sequence sebagai gantinya :

  INSERT INTO persons (lastname,firstname) VALUES ('Smith', 'John');
  SELECT currval(pg_get_serial_sequence('persons','id'));

Peringatan:currval() hanya berfungsi setelah INSERT (yang telah mengeksekusi nextval() ), dalam sesi yang sama .

Opsi 2:LASTVAL();

Ini mirip dengan yang sebelumnya, hanya saja Anda tidak perlu menentukan nama urutan:ini mencari urutan modifikasi terbaru (selalu di dalam sesi Anda, peringatan yang sama seperti di atas).

Keduanya CURRVAL dan LASTVAL benar-benar bersamaan aman. Perilaku urutan di PG dirancang agar 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 potensi masalah yang halus. Jika database memiliki beberapa PEMICU (atau ATURAN) itu, pada penyisipan ke persons tabel, buat beberapa penyisipan tambahan di tabel lain... lalu LASTVAL mungkin akan memberi kita nilai yang salah. Masalahnya bahkan dapat terjadi dengan CURRVAL , jika penyisipan tambahan dilakukan ke persons yang sama tabel (ini lebih jarang terjadi, tetapi risikonya tetap ada).

Opsi 3:INSERT dengan RETURNING

INSERT INTO persons (lastname,firstname) VALUES ('Smith', 'John') RETURNING id;

Ini adalah cara yang paling bersih, efisien dan aman untuk mendapatkan id. Itu tidak memiliki risiko sebelumnya.

Kekurangan? Hampir tidak ada:Anda mungkin perlu mengubah cara Anda memanggil pernyataan INSERT Anda (dalam kasus terburuk, mungkin lapisan API atau DB Anda tidak mengharapkan INSERT untuk mengembalikan nilai); itu bukan SQL standar (siapa peduli); ini tersedia sejak Postgresql 8.2 (Des 2006...)

Kesimpulan:Jika bisa, pilih opsi 3. Di tempat lain, pilih 1.

Catatan:semua metode ini tidak berguna jika Anda bermaksud mendapatkan id yang terakhir dimasukkan secara global (belum tentu menurut sesi Anda). Untuk ini, Anda harus menggunakan SELECT max(id) FROM table (tentu saja, ini tidak akan membaca sisipan yang tidak terikat dari transaksi lain).

Sebaliknya, Anda harus tidak pernah gunakan SELECT max(id) FROM table alih-alih salah satu dari 3 opsi di atas, untuk mendapatkan id yang baru saja dibuat oleh INSERT . Anda pernyataan, karena (terlepas dari kinerja) ini tidak aman secara bersamaan:antara INSERT . Anda dan SELECT sesi lain mungkin telah memasukkan catatan lain.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Scaling PostgreSQL Menggunakan Connection Poolers &Load Balancers

  2. Apakah PostgreSQL mendukung kompresi tabel (fragmen) transparan?

  3. kolom postgres X tidak ada

  4. Mengambil Komentar dari DB PostgreSQL

  5. Buat PERAN PostgreSQL (pengguna) jika tidak ada