Cara mendapatkan auto-increment id berikutnya di mysql

114

Cara mendapatkan id berikutnya di mysql untuk memasukkannya ke dalam tabel

INSERT INTO payments (date, item, method, payment_code)
VALUES (NOW(), '1 Month', 'paypal', CONCAT("sahf4d2fdd45", id))
faressoft
sumber
1
gunakan auto_incrementkolom
rajut
Apakah Anda ingin id berikutnya , atau id dari baris yang sedang Anda masukkan? Artinya, haruskah id di akhir kode pembayaran menjadi id dari baris di mana kode pembayaran disimpan?
Mike
ID baris yang saat ini saya masukkan
faressoft
6
Dalam hal ini, gabungkan nilai saat Anda mengambilnya, bukan saat Anda menyisipkannya. Jauh lebih mudah seperti itu, dan Anda mengesampingkan mendapatkan id yang salah, atau harus menjalankan pembaruan - pikirkan apa yang akan terjadi jika baris yang baru saja Anda sisipkan diminta oleh klien lain, sebelum pembaruan memiliki kesempatan untuk dijalankan: klien akan berakhir dengan kode pembayaran yang tidak valid. Pada sistem lalu lintas rendah, hal itu mungkin tidak terjadi, tetapi saya tidak melihat pentingnya mengambil risiko.
Mike
... atau seperti yang ditunjukkan @binaryLV, penguncian sumber daya mungkin juga menyelesaikan masalah. Lihat: dev.mysql.com/doc/refman/5.5/en/lock-tables.html
Mike

Jawaban:

12

Gunakan LAST_INSERT_ID()dari kueri SQL Anda.

Atau

Anda juga bisa menggunakannya mysql_insert_id()untuk mendapatkannya menggunakan PHP.

Sarfraz
sumber
13
@Sarfraz: Pertanyaannya adalah tentang ID BERIKUTNYA, bukan yang TERAKHIR seperti yang Anda katakan menyebutkan LAST_INSERT_ID().
Felipe Pereira
1
Jika baris dihapus dalam tabel, maks akan salah
peterchaula
hanya catatan dari '17 - fungsi mysql * tidak digunakan lagi - di atas dapat dilakukan denganmysqli_insert_id
treyBake
siapa yang menandai ini sebagai jawaban? pertanyaannya adalah tentang memasukkan id berikutnya bukan yang terakhir.
Amit Shah
253

Kamu bisa memakai

SELECT AUTO_INCREMENT
FROM information_schema.tables
WHERE table_name = 'table_name'
AND table_schema = DATABASE( ) ;

atau jika Anda tidak ingin menggunakan information_schema, Anda dapat menggunakan ini

SHOW TABLE STATUS LIKE 'table_name'
ravi404
sumber
Terima kasih untuk dua opsi pertama .. Tapi yang ketiga hanya nomor dua yang dipanggil dari PHP .. Tidak yakin apa yang membuatnya lebih cepat pada database besar ...
Gerard ONeill
1
@GerardONe Menghapusnya
ravi404
3
karena cache digunakan untuk mengambil data dari information_schema.tables, solusi ini tidak berfungsi lagi untuk mysql 8.
Bruno
1
@Bruno bisakah Anda memposting referensi?
mvorisek
1
Status dokumen resmi ini yang di TABLES.AUTO_INCREMENT-cache dev.mysql.com/doc/refman/8.0/en/… . Blog Mysql juga memiliki beberapa posting tentang itu, tetapi sistem yang mereka sebutkan tampaknya sudah ketinggalan zaman: mysqlserverteam.com/… mysqlserverteam.com/…
Bruno
50

Anda bisa mendapatkan nilai kenaikan otomatis berikutnya dengan melakukan:

SHOW TABLE STATUS FROM tablename LIKE Auto_increment
/*or*/
SELECT `auto_increment` FROM INFORMATION_SCHEMA.TABLES
WHERE table_name = 'tablename'

Perhatikan bahwa Anda tidak boleh menggunakan ini untuk mengubah tabel, gunakan kolom auto_increment untuk melakukannya secara otomatis.
Masalahnya adalah last_insert_id()retrospektif dan dengan demikian dapat dijamin dalam koneksi saat ini.
Bayi ini prospektif dan oleh karena itu tidak unik per sambungan dan tidak dapat diandalkan.
Hanya dalam satu database koneksi yang akan berfungsi, tetapi database koneksi tunggal hari ini memiliki kebiasaan menjadi beberapa database koneksi besok.

Lihat: SHOW TABLE STATUS

Johan
sumber
5
Saya tidak menurunkannya, tetapi masalah dengan mencoba menggunakan nilai penambahan otomatis terakhir adalah bahwa itu mungkin bukan yang terakhir pada saat Anda menggunakannya - tidak peduli seberapa cepat SELECT dan INSERT berikutnya dilakukan.
Mike
@ Mike, bagaimana jika itu dilakukan dalam satu kueri? Sesuatu seperti insert into table_name (field1, field2) select 'constant', auto_increment from information_schema.tables where table_name = 'table_name'? Saya akan menggunakan pemutakhiran di after inserttrigger dan last_insert_id(), meskipun ...
binaryLV
1
@binaryLV: Semakin kecil jarak antara SELECT dan INSERT, semakin kecil kemungkinan nilai akan berubah, tetapi itu tidak menutup kemungkinan sepenuhnya. Bayangkan sebuah sistem dengan ribuan klik per menit di database - kemungkinan nilainya berubah meningkat secara dramatis. Penguncian tabel atau baris dapat mencegah hal ini jika dilakukan sebagai kueri tunggal, tetapi itu bergantung pada perilaku tertentu dari mesin database yang mungkin tidak terdokumentasi dengan baik. Aku akan pergi dengan yang berikutnya UPDATEjika aku juga. Tapi saya lebih suka menggabungkan keduanya pada waktu tampilan, dan menghemat semua kerumitan.
Mike
3
SHOW TABLE STATUSberharap untuk melihat database namesetelah FROMdan 'table name pattern'sesudah LIKE.
x-yuri
2
karena cache digunakan untuk mengambil data dari information_schema.tables, solusi ini tidak berfungsi lagi untuk mysql 8.
Bruno
15

Ini akan mengembalikan nilai kenaikan otomatis untuk database MySQL dan saya tidak memeriksa dengan database lain. Harap dicatat bahwa jika Anda menggunakan database lain, sintaks kueri mungkin berbeda.

SELECT AUTO_INCREMENT 
FROM information_schema.tables
WHERE table_name = 'your_table_name'
     and table_schema = 'your_database_name';

SELECT AUTO_INCREMENT 
FROM information_schema.tables
WHERE table_name = 'your_table_name'
     and table_schema = database();
Bandara Chaminda
sumber
PILIH AUTO_INCREMENT DARI information_schema.tables WHERE table_name = 'your_table_name' dan table_schema = 'your_database_name';
LJay
10

Jawaban teratas menggunakan PHP MySQL_ untuk solusinya, saya pikir saya akan membagikan solusi PHP MySQLi_ yang diperbarui untuk mencapai ini. Tidak ada keluaran kesalahan dalam contoh ini!

$db = new mysqli('localhost', 'user', 'pass', 'database');
$sql = "SHOW TABLE STATUS LIKE 'table'";
$result=$db->query($sql);
$row = $result->fetch_assoc();

echo $row['Auto_increment'];

Menendang kenaikan Otomatis berikutnya yang muncul di tabel.

Hexchaimen
sumber
karena cache digunakan untuk mengambil data dari information_schema.tables, solusi ini tidak berfungsi lagi untuk mysql 8.
Bruno
9

Di PHP Anda dapat mencoba ini:

$query = mysql_query("SELECT MAX(id) FROM `your_table_name`");
$results = mysql_fetch_array($query);
$cur_auto_id = $results['MAX(id)'] + 1;

ATAU

$result = mysql_query("SHOW TABLE STATUS WHERE `Name` = 'your_table_name'");
$data = mysql_fetch_assoc($result);
$next_increment = $data['Auto_increment'];
Naresh Jain
sumber
5
Ingatlah dengan metode pertama jika record dengan id tertinggi dihilangkan, Anda kemudian akan membuat record baru dengan id yang sebelumnya dimiliki.
Tom Jenkinson
dan jika kunci sebelumnya digunakan di tabel lain dan masih disimpan di sana, Anda akan mendapatkan sihir yang sangat aneh
Tebe
yang pertama mengembalikan id yang salah jika Anda menjatuhkan catatan yang terakhir dimasukkan,
Ali Parsa
6

Larutan:

CREATE TRIGGER `IdTrigger` BEFORE INSERT ON `payments`
  FOR EACH ROW
BEGIN

SELECT  AUTO_INCREMENT Into @xId
    FROM information_schema.tables
    WHERE 
    Table_SCHEMA ="DataBaseName" AND
    table_name = "payments";

SET NEW.`payment_code` = CONCAT("sahf4d2fdd45",@xId);

END;

"DataBaseName" adalah nama dari Data Base kami

malaikat
sumber
5

Permintaan sederhana akan dilakukan SHOW TABLE STATUS LIKE 'table_name'

Raa
sumber
4

Anda dapat menggunakan pemicu mysql

Nick Pavluk
sumber
Memperbarui payment_codedalam after insertmemicu tampaknya menjadi pilihan terbaik.
binaryLV
3

Anda tidak dapat menggunakan ID saat memasukkan, Anda juga tidak membutuhkannya. MySQL bahkan tidak mengetahui ID saat Anda memasukkan catatan itu. Anda bisa menyimpan "sahf4d2fdd45"di payment_codetabel dan menggunakan iddan payment_codenanti.

Jika Anda benar-benar membutuhkan payment_code Anda untuk memiliki ID di dalamnya, UPDATE baris setelah sisipkan untuk menambahkan ID.

Yakub
sumber
+1 Untuk membuatnya sedikit lebih eksplisit: jika Anda mengambil nilai 'terbaru' dari kolom, itu hanya dijamin menjadi nilai terbaru tepat saat Anda mengambilnya. Ini mungkin bukan nilai terbaru saat Anda menggunakan nilai itu di sisipan berikutnya. Dalam kasus kolom kenaikan otomatis, selalu ada kemungkinan bahwa nilai lain telah ditambahkan antara waktu Anda mengambil id dan waktu Anda memasukkannya ke tempat lain. Jika Anda mereferensikan baris yang baru saja Anda sisipkan, menggunakan LAST_INSERT_ID () tidak masalah. Jika Anda mencoba untuk memastikan nilai unik, sebenarnya tidak.
Mike
@cularis, MySQL mengetahui id auto_increment berikutnya, itu tercantum dalam information_schema.tablestabel.
Johan
1
@faressoft: Jika idenya adalah memiliki kode pembayaran yang terdiri dari string unik ditambah id dari baris yang berisi kode pembayaran tersebut, cukup gabungkan keduanya saat Anda mengambil baris - baik dengan a SELECT ... CONCAT(payment_code, id), atau dalam kode aplikasi Anda. Anda bahkan bisa membungkusnya dengan SELECTa VIEW, sehingga Anda selalu mengembalikan nilai yang benar, tanpa mengkhawatirkan CONCAT di setiap SELECT dari aplikasi Anda.
Mike
3

Untuk apa Anda memerlukan ID inkremental berikutnya?

MySQL hanya mengizinkan satu bidang kenaikan otomatis per tabel dan itu juga harus menjadi kunci utama untuk menjamin keunikan.

Perhatikan bahwa ketika Anda mendapatkan ID penyisipan berikutnya, ID tersebut mungkin tidak tersedia saat Anda menggunakannya karena nilai yang Anda miliki hanya dalam cakupan transaksi itu. Oleh karena itu, bergantung pada beban pada database Anda, nilai tersebut mungkin sudah digunakan pada saat permintaan berikutnya masuk.

Saya menyarankan agar Anda meninjau desain Anda untuk memastikan bahwa Anda tidak perlu mengetahui nilai kenaikan otomatis mana yang akan ditetapkan selanjutnya

Stephen Senkomago Musoke
sumber
Bukan ide yang baik untuk mengasumsikan jenis aplikasi yang membutuhkan ID. Ada aplikasi seperti yang saya kerjakan saat ini yang membutuhkan ID tambahan berikutnya dan nilai yang diambil tidak berbahaya dialokasikan ke skrip lain.
JG Estiot
3

Saya menyarankan untuk memikirkan kembali apa yang Anda lakukan. Saya tidak pernah mengalami satu pun kasus penggunaan yang membutuhkan pengetahuan khusus itu. Id berikutnya adalah detail implementasi yang sangat khusus dan saya tidak berharap mendapatkannya aman dari ACID.

Lakukan satu transaksi sederhana yang memperbarui baris yang Anda masukkan dengan id terakhir:

BEGIN;

INSERT INTO payments (date, item, method)
     VALUES (NOW(), '1 Month', 'paypal');

UPDATE payments SET payment_code = CONCAT("sahf4d2fdd45", LAST_INSERT_ID())
     WHERE id = LAST_INSERT_ID();

COMMIT;
Markus Malkusch
sumber
Saya dapat memberi tahu satu kasus penggunaan seperti itu, saya mencoba mendiagnosis masalah produksi, jadi saya perlu mencari tahu apakah baris terakhir dalam tabel benar-benar baris terakhir atau jika ada yang ditambahkan setelah itu yang entah bagaimana terhapus, tabel memiliki bidang auto_increment di dalamnya, jadi dengan menemukan informasi ini saya dapat menyimpulkan apakah baris tersebut telah dihapus atau tidak pernah ditambahkan.
Usman
1
Itu mungkin berhasil untuk Anda, tetapi saya tidak akan mengandalkannya karena menurut saya Anda tidak memiliki jaminan untuk itu: dev.mysql.com/doc/refman/8.0/en/example-auto-increment.html " ketika kolom AUTO_INCREMENT adalah bagian dari indeks multi-kolom), nilai AUTO_INCREMENT digunakan kembali jika Anda menghapus baris dengan nilai AUTO_INCREMENT terbesar di grup mana pun. "
Markus Malkusch
Terima kasih, informasi yang berguna, juga sesuai tautan Anda yang dibagikan auto_increment dapat diatur ulang secara manual memasukkan nomor, jadi ya tidak dapat diandalkan.
Usman
2

Anda harus terhubung ke MySQL dan memilih database sebelum Anda dapat melakukan ini

$table_name = "myTable"; 
$query = mysql_query("SHOW TABLE STATUS WHERE name='$table_name'"); 
$row = mysql_fetch_array($query); 
$next_inc_value = $row["AUTO_INCREMENT"];  
jondinham.dll
sumber
2

gunakan "mysql_insert_id ()". mysql_insert_id () bertindak pada kueri yang terakhir dilakukan, pastikan untuk memanggil mysql_insert_id () segera setelah kueri yang menghasilkan nilai.

Di bawah ini adalah contoh penggunaan:

<?php
    $link = mysql_connect('localhost', 'username', 'password');
if (!$link) {
    die('Could not connect: ' . mysql_error());
}
mysql_select_db('mydb');

mysql_query("INSERT INTO mytable  VALUES('','value')");
printf("Last inserted record has id %d\n", mysql_insert_id());
    ?>

Semoga contoh di atas bermanfaat.

Sagar Chavda
sumber
Terima kasih saya menyadarinya.
Tn. Javed Multani
1
mysql_insert_id();

Itu dia :)

pengguna3814281
sumber
1
SELECT id FROM `table` ORDER BY id DESC LIMIT 1

Meski saya ragu dengan produktivitasnya tapi 100% bisa diandalkan

Tebe
sumber
Saya juga setuju ini adalah pendekatan yang paling sederhana. Tidak yakin mengapa Anda tidak dipilih, tetapi saya akan mengimbangi dengan suara positif.
berulang
Saya tidak menyebutkan perlunya transaksi, jika Anda tidak membungkusnya di dalam transaksi, kode ini buruk secepat mungkin memenuhi pemuatan nyata.
Tebe
1
Bagaimana jika baris terakhir dihapus? Atau beberapa baris terbaru telah dihapus?
Liam W
Non-issue, kunci bebas tidak akan digunakan kecuali Anda menentukannya secara eksplisit
Tebe
1

menggunakan jawaban ravi404:

CREATE FUNCTION `getAutoincrementalNextVal`(`TableName` VARCHAR(50))
    RETURNS BIGINT
    LANGUAGE SQL
    NOT DETERMINISTIC
    CONTAINS SQL
    SQL SECURITY DEFINER
    COMMENT ''
BEGIN

    DECLARE Value BIGINT;

    SELECT
        AUTO_INCREMENT INTO Value
    FROM
        information_schema.tables
    WHERE
        table_name = TableName AND
        table_schema = DATABASE();

    RETURN Value;

END

menggunakan kueri sisipkan Anda, untuk membuat Hash SHA1. ex.:

INSERT INTO
    document (Code, Title, Body)
VALUES (                
    sha1( getAutoincrementalNextval ('document') ),
    'Title',
    'Body'
);
Paulo A. Costa
sumber
Apakah ini selalu berhasil? Apakah ada ketentuan balapan jika dua sisipan terjadi pada waktu yang bersamaan?
Jmons
0

Peningkatan @ ravi404, jika offset penambahan otomatis Anda BUKAN 1:

SELECT (`auto_increment`-1) + IFNULL(@@auto_increment_offset,1) 
FROM INFORMATION_SCHEMA.TABLES
WHERE table_name = your_table_name
AND table_schema = DATABASE( );

( auto_increment-1): db engine tampaknya selalu mempertimbangkan offset 1. Jadi, Anda perlu membuang asumsi ini, lalu menambahkan nilai opsional @@ auto_increment_offset, atau default ke 1: IFNULL (@@ auto_increment_offset, 1)

Olivier
sumber
0

Bagi saya ini berfungsi, dan terlihat sederhana:

 $auto_inc_db = mysql_query("SELECT * FROM my_table_name  ORDER BY  id  ASC ");
 while($auto_inc_result = mysql_fetch_array($auto_inc_db))
 {
 $last_id = $auto_inc_result['id'];
 }
 $next_id = ($last_id+1);


 echo $next_id;//this is the new id, if auto increment is on
Toncsiking
sumber
Cukup tidak perlu untuk menetapkan $last_idberulang-ulang bila Anda bisa saja DESC. whileBlok Anda melakukan banyak pekerjaan yang tidak berguna.
Tiw
ya, benar ... saya baru menyadari itu tidak sempurna ... :( akhiri orang dapat mengulangi id, jika dihapus sebelumnya ... :(
Toncsiking
0

Jika tidak mengembalikan AUTO_INCREMENT yang benar, cobalah:

ANALYZE TABLE `my_table`;
SELECT AUTO_INCREMENT FROM information_schema.TABLES WHERE (TABLE_NAME = 'my_table');

Cache yang jelas ini untuk tabel, di BD

Vanom
sumber