PHP'de bir MySQL tablosunun son eklenen kimliğini nasıl alırım?


93

Sık sık yeni verilerin eklendiği bir tablom var. Tablonun son kimliğini almam gerekiyor. Bunu nasıl yapabilirim?

Benzer SELECT MAX(id) FROM tablemi?


1
evet, bu sorgu tablonun son kimliğini döndürecektir. Ancak bir koşul, kimliğin Birincil anahtar olması gerektiğidir. Böylece tövbe etmekten kaçınabilirsiniz.
sathish

7
@sathish: Bu yöntemin temel sorunu eşzamanlılıktır .
Christian C. Salvadó

3
Detaylandırmak için: Bununla ilgili sorun, sizin INSERTve sorgunuzun arasına başka biri tabloya bir şey eklerse , son kimliğiniz MAX(id)olmayan bir kimlik elde edebilirsiniz .
deceze

3
@Jocelyn bu soru bir yıl sonra bu sorudan binlerce daha az görüşle soruldu.
Naftali aka Neal

3
@Neal, haklısın. Diğer soru, bunun kopyası olarak kapatılmalıdır.
Jocelyn

Yanıtlar:


134

PDO kullanıyorsanız, kullanın PDO::lastInsertId.

Mysqli kullanıyorsanız, kullanın mysqli::$insert_id.

Hala Mysql kullanıyorsanız:

Lütfen mysql_*yeni kodda işlev kullanmayın . Artık korunmuyorlar ve resmi olarak kullanımdan kaldırılıyorlar . Bkz kırmızı kutuyu ? Bunun yerine hazırlanmış ifadeler hakkında bilgi edininve PDO veya MySQLi kullanın - bu makale hangisi olduğuna karar vermenize yardımcı olacaktır. PDO'yu seçerseniz, işte size iyi bir eğitim .

Ama mecbursan kullan mysql_insert_id.


Bununla ilgili sorun, çok sayıda ekiniz varsa (örneğin, veritabanınız da bir şeyler kaydederse) yanlış kimliği alabilirsiniz.
Mike

Eğer kullanırsanız değil @ Mike mysql_insert_id hemen sonra SİZİN mysql_query. Elbette, aynı bağlantı üzerinden birkaç başka sorgu yürütürseniz, orada size yardımcı olabilecek hiçbir şey yoktur.
kestirmek

7
ASLA yanlış bir kimlik almayacağınızı garanti etmek için kodunuzu bir TRANSACTION ile sarın .
Marcelo Assis

28
mysql, bunun GÜNCEL BAĞLANTININ son kimliği olduğundan emin olur, bu nedenle bu ifadeyi ekleme sorgusunun hemen sonrasına koyarsanız sorun olmaz. Ekleme yapan diğer işlemler hakkında endişelenmenize gerek yok, bunu bir işlemle sarmalamaya gerek yok. Mysql kılavuzu şöyle der: "Oluşturulan kimlik, sunucuda bağlantı bazında tutulur. Bu, işlev tarafından belirli bir istemciye döndürülen değerin, bir AUTO_INCREMENT sütununu etkileyen en son ifade için oluşturulan ilk AUTO_INCREMENT değeri olduğu anlamına gelir. tarafından bu istemci Bu gerektiğini nedenidir. değil MAX (ID) seçmek kullanmak
woens

1
@deceze, PDOher yerde gördüğümüz bu önyargı nedir ? Özellik karşılaştırmasına tekrar bakalım . mysqliEllerinizi düşük seviyeli şeylerle kirletmeniz gerektiğinde kazananın olduğu açıktır . Başka bir deyişle, PDO seçilse bile, sonundamysqli yine de kullanması gerekecektir.
Pacerier

52

mevcut bağlantıya eklenen son kimliğin ne olduğunu bilmek için bir işlev var

mysql_query('INSERT INTO FOO(a) VALUES(\'b\')');
$id = mysql_insert_id();

artı kullanarak max bir olan kötü bir fikir o yol açabilir, çünkü sorunların kodunuzu iki farklı oturumlarda aynı anda kullanılması durumunda.

Bu işleve mysql_insert_id denir


2
mysql _ (...) PHP> = 5.5 sürümünde kullanımdan kaldırılmıştır.
Iago

Evet, bunu sadece hatırlıyorum. :)
Iago



8

Yazdıklarınız id, benzersiz olduklarını ve otomatik olarak artırıldıklarını varsayarsak size en iyisini verirdi; bu, davet eşzamanlılık sorunlarında sorun olmadığını varsayarsak iyi olur.
Veritabanınız olarak MySQL kullandığınız için, LAST_INSERT_ID()yalnızca eklemeyi yapan mevcut bağlantıda çalışan belirli bir işlev vardır.
PHP, çağrılanlar için özel bir işlev sunar mysql_insert_id.


6

Bunu deneyin iyi çalışmalı:

$link = mysqli_connect("localhost", "my_user", "my_password", "world");

$query = "INSERT blah blah blah...";
$result = mysqli_query($link, $query);

echo mysqli_insert_id($link);

1
Fark ettiğin için teşekkürler. Kodu düzenledim, aslında bu $ link (bağlantıyı tutan değişken)
Sandhu

3

Kod işaretleyiciye en son eklenen kimliği almak için Ekleme sorgusunu çalıştırdıktan sonra insert_id(), veritabanında çağrılan bir işlevi kullanın , son eklenen kimliği döndürür

Ör:

$this->db->insert('mytable',$data);
echo $this->db->insert_id(); //returns last inserted id

tek satırda

echo $this->db->insert('mytable',$data)->insert_id();

2

Dahili php işlevi ile en son eklenen kimliği alabilirsiniz mysql_insert_id();

$id = mysql_insert_id();

ayrıca en son kimliği de alırsınız

$id = last_insert_id();

5
Ayrıca, bu yanlış çünkü kullanımdan kaldırılmış bir kitaplık kullanmayı öneriyor. Gerçekten, bunu sil
STT LCU 13

@STTLCU Burada hangi snippet kullanımdan kaldırıldı?
TheBlackBenzKid

@TheBlackBenzKid her ikisi de, çünkü bunlar mysql_ * işlevlerine dayanıyor
STT LCU

@Rahul $ id = last_insert_id (); kullanımdan kaldırıldığı gibi çalışmıyor.
Esha

2

Kullanmakta sorun yok mysql_insert_id(), ancak kullanımıyla ilgili belirli bir not var, INSERT sorgusunu çalıştırdıktan sonra çağırmalısınız, yani aynı komut dosyası oturumunda. Aksi takdirde kullanırsanız düzgün çalışmayacaktır.


2

Temiz ve Basit -

$selectquery="SELECT id FROM tableName ORDER BY id DESC LIMIT 1";
$result = $mysqli->query($selectquery);
$row = $result->fetch_assoc();
echo $row['id'];

1

NOT: tek bir deyimle birden çok ekleme yaparsanız, mysqli :: insert_id doğru olmayacaktır.

Tablo:

create table xyz (id int(11) auto_increment, name varchar(255), primary key(id));

Şimdi yaparsan:

insert into xyz (name) values('one'),('two'),('three');

Mysqli :: insert_id 3 değil 1 olacaktır.

Doğru değeri elde etmek için şunları yapın:

mysqli::insert_id + mysqli::affected_rows) - 1

Bu bir belgeydi ama biraz belirsiz.


1

İstediğim tablonun son auto_increment kimliğini almak için saf bir MySQL sözdizimi kullanmayı tercih ederim.

php mysql_insert_id () ve mysql last_insert_id () yalnızca son işlem kimliğini verir.

Şemanızdaki herhangi bir tablonun son otomatik_artımlı kimliğini istiyorsanız (yalnızca son işlemi değil), bu sorguyu kullanabilirsiniz

SELECT AUTO_INCREMENT FROM information_schema.TABLES
    WHERE TABLE_SCHEMA = 'my_database' 
    AND TABLE_NAME = 'my_table_name';

Bu kadar.


Bu konuda şüpheliyim, çünkü bu SQL soru bağlamında yanlıştır .... Ayrıca bu yöntem, iki veya daha fazla istemci bu SQL'i aynı anda çalıştırdığında olası yarış koşullarına yatkın hissediyor ... Emin değilim Bu sütun verilerinin bir eklemeden sonra ne kadar hızlı güncellendiği beni şüphe uyandırıyor ... Son kimliği alabilen PHP işlevleri bağlantı / oturum seviyesine dayanır (aşağı yukarı MySQL'in LAST_INSERT_ID () ile aynıdır ) ve bu da onu yarış durumunu kaydetmeye dönüştürür
Raymond Nijland 8'19

1

Örnekle herhangi bir cevap görmemek üzücü.

Mysqli :: $ insert_id kullanarak :

$sql="INSERT INTO table (col1, col2, col3) VALUES (val1, val2, val3)";
$mysqli->query($sql);
$last_inserted_id=$mysqli->insert_id; // returns last ID

PDO :: lastInsertId kullanarak :

$sql="INSERT INTO table (col1, col2, col3) VALUES (val1, val2, val3)";
$database->query($sql);
$last_inserted_id=$database->lastInsertId(); // returns last ID

0

MySQLiİşlemi kullanarak bazen mysqli::$insert_id0 döndürdüğü için alamadım. Özellikle saklı yordamları kullanıyor olsaydım, o yürütüldü INSERT. Yani işlem içinde başka bir yol var:

<?php

function getInsertId(mysqli &$instance, $enforceQuery = false){
    if(!$enforceQuery)return $instance->insert_id;

    $result = $instance->query('SELECT LAST_INSERT_ID();');

    if($instance->errno)return false;

    list($buffer) = $result->fetch_row();

    $result->free();

    unset($result);

    return $buffer;
}

?>

0

Kullanım mysqli olarak MySQL depricating olduğunu

<?php
$mysqli = new mysqli("localhost", "yourUsername", "yourPassword", "yourDB");

/* check connection */
if (mysqli_connect_errno()) {
    printf("Connect failed: %s\n", mysqli_connect_error());
    exit();
}
// Conside employee table with id,name,designation
$query = "INSERT INTO myCity VALUES (NULL, 'Ram', 'Developer')";
$mysqli->query($query);

printf ("New Record has id %d.\n", $mysqli->insert_id);

/* close connection */
$mysqli->close();
?>

-1

denedim

mysqli_insert_id($dbConnectionObj)

Bu, mevcut bağlantının en son eklenen kimliğini döndürür, bu nedenle bağlantılarınızı düzgün bir şekilde yönetiyorsanız bu çalışmalıdır. En azından benim için çalıştı.


1
Bu, buradaki yanıtın aynısıdır stackoverflow.com/a/41564156/5468463
Vega

Olumsuz oy sayısıyla, bu gereksiz görev, moderatörleri rahatsız etmek yerine topluluk tarafından temizlenebilir.
mickmackusa
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.