Mysql insert sorgusundan yeni kayıt birincil anahtar kimliğini al?


249

Tamam, bu yüzden bir mysql yapıyorum diyelim INSERTbenim tablolardan birinin içine ve masa sütunu vardır item_idayarlandığında autoincrementve primary key.

Sorguyu item_idaynı sorguda yeni oluşturulan birincil anahtarın değerini almak için nasıl edinebilirim ?

Şu anda kimliğini almak için ikinci bir sorgu çalıştırıyorum ama bu neredeyse yanlış sonuç üretebilir düşünüyor iyi uygulama gibi görünüyor ...

Bu mümkün değilse, doğru kimliği almayı sağlamak için en iyi uygulama nedir?


1
Böyle bir INSERTsorgudan herhangi bir şey döndürmenin bir yolu yoktur ; neden yanlış sonuç verebileceğini düşünüyorsunuz?
Patlama Hapları

4
Süreç 2 kişi tarafından ayrı ayrı yürütülürse, bence üst üste binen bir süreç listesi alabilirsin - çünkü 2 ayrı sorgu yürütmek zorundasın?
Amy Neville


@JimFell evet temelde aynı soru, ama bu genel olarak çok daha iyi cevapları var
RozzA

1
Postgresql kullanın ve sonra bu INSERT INTO tablosu (col1, col2) DEĞERLERİ (val1, val2) DÖNÜŞ kimliği veya INSERT INTO tablosu (col1, col2) DEĞERLERİ (val1, val2) DÖNÜŞ * veya GÜNCELLEME tablosu SET'i col1 = val1, col2 = val2 WHERE deyimi RETURNING id veya UPDATE tablo SET (col1, col2) = (val1, val2) WHERE deyimi RETURNING id veya UPDATE tablo SET (col1, col2) = (val1, val2) WHERE deyimi RETURNING *
gdarcan

Yanıtlar:


327

Bu LAST_INSERT_ID()işlevi kullanmanız gerekir : http://dev.mysql.com/doc/refman/5.0/en/information-functions.html#function_last-insert-id

Örneğin:

INSERT INTO table_name (col1, col2,...) VALUES ('val1', 'val2'...);
SELECT LAST_INSERT_ID();

Bu geri alacak PRIMARY KEYo son satırın değerini sen takılı:

Oluşturulan kimlik, bağlantı başına sunucuda tutulur . Bu, işlev tarafından belirli bir istemciye döndürülen değerin , o istemci tarafından bir AUTO_INCREMENT sütununu etkileyen en son ifade için oluşturulan ilk AUTO_INCREMENT değeri olduğu anlamına gelir .

Dolayısıyla, döndürülen değer LAST_INSERT_ID()kullanıcı başınadır ve sunucuda diğer kullanıcılardan çalıştırılabilecek diğer sorgulardan etkilenmez .


8
evet ama aradaki (işlem listesindeki sorgular arasında) başka bir satır eklenmişse ne olur? Ekleme sorgusu bunu çıktısını almak için yazmak için herhangi bir yolu var mı?
Amy Neville

Tamam, görüyorum ... sonuçta oturum açmasa bile sorgunun son ekleme kimliği kaydedilir ... $ mysqli-> insert_id
Amy Neville

27
Bu geri alacak PRIMARY KEYo son satırın değerini Eğer sunucuya her bağlantı bunun için kendi değer koruyacak - bu bağlantı başına, çünkü takılı. Bunu açıklığa kavuşturmak için cevabı güncelledim.
Duncan Lock

Bu yüzden 3 kullanıcının aynı anda formlarını gönderdiğini ve veritabanımın bunları girmesi gerektiğini varsayalım. Tablo2'de yeni oluşturulan her table1 kimliğine karşılık gelen bir satır eklemek istiyorum. Eşzamanlılık, gelen veritabanı yazma istekleri için halledilir mi yoksa PHP ile manuel olarak mı yapmam gerekir?
bad_keypoints

Table1 ekini yaptığınız noktada, veritabanı table2'ye eklemek istediğiniz tüm bilgileri biliyorsa, bunu yapmak için bir tetikleyici kullanabilir veya bunu bir sorguda birleştirebilirsiniz. Değilse, birden çok sorgu kullanmanız gerekir - yani PHP'de yapın. Verilerin ne olduğuna ve ikinci kesici uç için nereden geldiğine bağlıdır.
Duncan Lock

21

DİKKAT !! PHP içinde bu birincil anahtar değerini döndürmeye çalışıyorsanız "LAST_INSERT_ID ()"

Ben bu konu php etiketli olmadığını biliyorum, ama bu cevapla karşılaşan herkes için standart mysql_query çağrıları kullanarak bir PHP komut dosyası ekleme bir MySQL insert kimliği döndürmek isteyen - bu çalışma alışkanlık ve SQL hataları yakalamadan açık değildir.

Daha yeni mysqli birden çok sorguyu destekler - ki bu LAST_INSERT_ID () aslında orijinalinden ikinci bir sorgudur.

IMO son birincil anahtarı tanımlamak için ayrı bir SELECT, önceki INSERT işleminden oluşturulan AUTO_INCREMENT ID döndüren isteğe bağlı mysql_insert_id () işlevinden daha güvenlidir.


7
LAST_INSERT_IDbağlantı başına MySQL işlevidir. Son ekleme kimliğini sorgularsanız, ayrı bir bağlantı yazma gerçekleştirmiş olabilir ve yanlış kimliğiniz olacaktır.
Patlama Hapları

@ExplosionPills mysql_insert_id()bağlantı başına da çalışır, ancak burada görüldüğü gibi garip davranışlar yaşar Cliffoverlife'ın yorumunda stackoverflow.com/a/897374/1305910 - nevermind hepimiz kullanmalıyızmysqli
RozzA

'işe yaramaz' kaldığınızda ne demek istediğinizi açıklayabilir misiniz?
john ktejik

18

Gönderen LAST_INSERT_ID()belgeler:

Oluşturulan kimlik sunucuda bağlantı başına korunur

Komut dosyasına aynı anda iki ayrı isteğiniz varsa, bunlar birbirlerini etkilemezler LAST_INSERT_ID()(belki de kalıcı bir bağlantı kullanmıyorsanız).


2
Tablonuz başka bir tabloya bir ekleme yapar üzerinde bir tetik varsa şüpheli olduğunu düşünüyorum .... LAST_INSERT_ID () diğer tablonun id değerini dönecektir ..
bgies

15

Burada aradığın şey !!!

select LAST_INSERT_ID()

Bu, SCOPE_IDENTITY()kullanılan fonksiyonun en iyi alternatifidir SQL Server.

Bunun yalnızca sorgunuz Last_INSERT_ID()tarafından tetiklendikten sonra çalışacağını da unutmayın Insert. Yani sorgu şemaya eklenen kimliği döndürür. Belirli bir tablonun son eklenen kimliğini alamazsınız.

Daha fazla ayrıntı için lütfen mySQL'deki SQLServer işlevinin SCOPE_IDENTITY () eşdeğeri bağlantısını inceleyin.


6

Satır eklemeden önce değere ihtiyacınız varsa:

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

Bunu bir prospektüste kullanabilirsiniz:

INSERT INTO
    document (Code, Title, Body)
VALUES (                
    sha1( concat (convert ( now() , char), ' ',   getAutoincrementalNextval ('document') ) ),
    'Title',
    'Body'
);

1
Bu iyi bir fikir gibi görünmüyor mu? 2 istemci aynı işlevi aynı anda çağırırsa, gerçekte olmadıklarında aynı kimliği eklediklerini düşüneceklerdir ... biri ekte biraz daha yavaş olacak ve bilmeden bir sonraki kimliği alacaktır.
CarCar

5

Bu parametreleri sorgu sonucunuzda alacaksınız:

    "fieldCount": 0,
    "affectedRows": 1,
    "insertId": 66,
    "serverStatus": 2,
    "warningCount": 1,
    "message": "",
    "protocol41": true,
    "changedRows": 0

insertIdEğer tam ihtiyacımız olan şey.

(NodeJS-mySql)


4

Eğer pytysql kullanarak python ise, imleçten cursor.lastrowid kullanabilirsiniz


2

"$ last_id = mysqli_insert_id ($ conn);"


2
Aslında burada google sayesinde bu cevabın php sürümünü arayan tökezledi, bu yüzden bu cevaba oy verdi. Teknik olarak OP php için sormadı, ancak bu da burada yanılmak bir sürü insan için yararlı olabilir.
Fotoğrafçı Britt

Çok teşekkür ederiz Arnav! I
JuanSedano

1

PHP kullanıyorsanız: Bir PDO nesnesinde , ekleme işleminden sonra lastInsertId yöntemini basitçe çağırabilirsiniz .

Aksi takdirde bir LAST_INSERT_ID ile aşağıdaki gibi bir değer elde edebilirsiniz:SELECT LAST_INSERT_ID();



0

Ben sadece PHP bu yaklaşımımı paylaşmak istiyorum, bazılarınız verimli bir yol bulamadı ama bu diğer mevcut seçeneklere göre 100 daha iyi.

rastgele bir anahtar oluşturun ve yeni bir satır oluşturarak tabloya ekleyin. birincil anahtarı almak için bu tuşu kullanabilirsiniz. veri eklemek ve başka şeyler yapmak için güncellemeyi kullanın.

bu şekilde bir satır güvenli hale getirilir ve doğru birincil anahtar bulunur.

Başka seçeneğiniz olmadığı sürece bunu gerçekten önermiyorum.

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.