PHP kullanarak MySQL'de son güncellenen satırın kimliğini nasıl alabilirim?
UPDATE foo WHERE bar = 1; SELECT id FROM foo WHERE bar = 1?
PHP kullanarak MySQL'de son güncellenen satırın kimliğini nasıl alabilirim?
UPDATE foo WHERE bar = 1; SELECT id FROM foo WHERE bar = 1?
Yanıtlar:
Bu soruna bir cevap buldum :)
SET @update_id := 0;
UPDATE some_table SET column_name = 'value', id = (SELECT @update_id := id)
WHERE some_other_column = 'blah' LIMIT 1;
SELECT @update_id;
DÜZENLEME aefxx tarafından
Bu teknik, bir güncelleme ifadesinden etkilenen her satırın kimliğini almak için daha da genişletilebilir:
SET @uids := null;
UPDATE footable
SET foo = 'bar'
WHERE fooid > 5
AND ( SELECT @uids := CONCAT_WS(',', fooid, @uids) );
SELECT @uids;
Bu, tüm kimliklerin virgülle birleştirildiği bir dize döndürür.
WHEREcümleniz olduğundan , bir WHEREsonraki sorgunuzda aynı cümleyi kullanabilirsinizSELECT id FROM footable WHERE fooid > 5
LAST_INSERT_ID()bir sonraki çağrı tarafından döndürülen değeri ayarlayacak bir argümanı kabul edebilir LAST_INSERT_ID(). Örneğin: UPDATE table SET id=LAST_INSERT_ID(id), row='value' WHERE other_row='blah';. Şimdi, SELECT LAST_INSERT_ID();güncellenmiş kimliği döndürecektir. Daha fazla ayrıntı için newtover'ın cevabına bakın.
UPDATE lastinsertid_test SET row='value' WHERE row='asd' AND LAST_INSERT_ID(id) OR LAST_INSERT_ID(0);. Ancak birden fazla kimliği almadığı için bu yanıt daha üstündür.
Hm, cevaplar arasında en kolay çözümü görmeme şaşırdım.
Diyelim ki, tablodaki item_idbir tamsayı kimlik sütunu itemsve satırları aşağıdaki ifadeyle güncelliyorsunuz:
UPDATE items
SET qwe = 'qwe'
WHERE asd = 'asd';
Ardından, ifadeden hemen sonra etkilenen en son satırı öğrenmek için, ifadeyi aşağıdaki şekilde biraz güncellemelisiniz:
UPDATE items
SET qwe = 'qwe',
item_id=LAST_INSERT_ID(item_id)
WHERE asd = 'asd';
SELECT LAST_INSERT_ID();
Yalnızca gerçekten değiştirilmiş satırı güncellemeniz gerekiyorsa, satırdaki verilerin değişip değişmeyeceğini kontrol ederek LAST_INSERT_ID aracılığıyla item_id için koşullu bir güncelleme eklemeniz gerekir.
UPDATE items SET qwe = 'qwe' WHERE asd = 'asd' AND LAST_INSERT_ID(item_id); SELECT LAST_INSERT_ID();
Bu resmi olarak basit ama dikkat çekici derecede sezgiseldir. Eğer yapıyorsan:
update users set status = 'processing' where status = 'pending'
limit 1
Şununla değiştirin:
update users set status = 'processing' where status = 'pending'
and last_insert_id(user_id)
limit 1
Eklenmesi last_insert_id(user_id)halinde wheremaddeye MySQL anlatıyor set FOUND sıranın kimliğine iç değişken. Bunu last_insert_id(expr)beğenmek için bir değer ilettiğinizde, bu değeri döndürür, ki buradaki gibi kimliklerde her zaman pozitif bir tam sayıdır ve bu nedenle her zaman true olarak değerlendirilir, where cümlesine asla müdahale etmez. Bu yalnızca bir satır gerçekten bulunursa işe yarar, bu nedenle etkilenen satırları kontrol etmeyi unutmayın. Daha sonra kimliği birden çok yolla alabilirsiniz.
LAST_INSERT_ID () 'yi çağırmadan diziler oluşturabilirsiniz, ancak işlevi bu şekilde kullanmanın faydası, kimlik değerinin sunucuda otomatik olarak oluşturulan son değer olarak tutulmasıdır. Çoklu kullanıcı güvenlidir çünkü birden çok istemci UPDATE deyimini yayınlayabilir ve kendi sıra değerlerini oluşturan diğer istemcileri etkilemeden veya onlardan etkilenmeden SELECT deyimiyle (veya mysql_insert_id ()) kendi sıra değerini alabilir.
Önceki INSERT veya UPDATE deyimiyle AUTO_INCREMENT sütunu için oluşturulan değeri döndürür. AUTO_INCREMENT alanı içeren bir tabloya INSERT deyimi uyguladıktan veya LAST_INSERT_ID (ifade) ile bir sütun değeri ayarlamak için INSERT veya UPDATE kullandıktan sonra bu işlevi kullanın.
LAST_INSERT_ID () ve mysql_insert_id () arasındaki farkın nedeni, LAST_INSERT_ID () 'nin komut dosyalarında kullanımı kolay hale getirilirken, mysql_insert_id () AUTO_INCREMENT sütununa ne olduğu hakkında daha kesin bilgi sağlamaya çalışmasıdır.
LAST_INSERT_ID () işlevini kullanarak bir INSERT veya UPDATE deyimi gerçekleştirmek, mysqli_insert_id () işlevi tarafından döndürülen değeri de değiştirecektir.
Hepsini bir araya koy:
$affected_rows = DB::getAffectedRows("
update users set status = 'processing'
where status = 'pending' and last_insert_id(user_id)
limit 1"
);
if ($affected_rows) {
$user_id = DB::getInsertId();
}
(Bilginize, DB sınıfı burada .)
Bu, Salman A'nın cevabı ile aynı yöntemdir, ancak işte bunu yapmanız gereken kod.
İlk olarak, tablonuzu bir satır değiştirildiğinde otomatik olarak takip edecek şekilde düzenleyin. Yalnızca bir satırın başlangıçta ne zaman eklendiğini bilmek istiyorsanız son satırı kaldırın.
ALTER TABLE mytable
ADD lastmodified TIMESTAMP
DEFAULT CURRENT_TIMESTAMP
ON UPDATE CURRENT_TIMESTAMP;
Ardından, son güncellenen satırı bulmak için bu kodu kullanabilirsiniz.
SELECT id FROM mytable ORDER BY lastmodified DESC LIMIT 1;
Bu kodun tamamı MySQL vs PostgreSQL'den kaldırılmıştır : Bir Tabloya 'Last Modified Time' Sütunu Ekleme ve MySQL Kılavuzu: Satırları Sıralama . Ben sadece monte ettim.
Sorgu :
$sqlQuery = "UPDATE
update_table
SET
set_name = 'value'
WHERE
where_name = 'name'
LIMIT 1;";
PHP işlevi:
function updateAndGetId($sqlQuery)
{
mysql_query(str_replace("SET", "SET id = LAST_INSERT_ID(id),", $sqlQuery));
return mysql_insert_id();
}
Benim için çalışıyor;)
Yukarıdakilere Daha Fazla Yanıt Kabul Edilmiş Cevap
Merak edenler için :=&=
Belirgin fark arasındaki :=ve =, ve bu yani :=ederken, her yerde değişken atama operatörü olarak çalışmalar =sadece SET tablolara bu şekilde çalışır ve her yerde bir karşılaştırma operatörüdür.
Yani SELECT @var = 1 + 1;bırakacak @vardeğişmeden ve bir dönüş boolean ederken, (1 veya 0 @ VAR şimdiki değerine bağlı olarak) SELECT @var := 1 + 1;değişecek @variçin 2 ve 2 dönüş .
[Kaynak]
Hey, sadece böyle bir numaraya ihtiyacım vardı - farklı bir şekilde çözdüm, belki senin için işe yarar. Bunun ölçeklenebilir bir çözüm olmadığını ve büyük veri kümeleri için çok kötü olacağını unutmayın.
Sorgunuzu iki bölüme ayırın -
önce, güncellemek istediğiniz satırların kimliklerini seçin ve bunları geçici bir tabloda saklayın.
ikinci olarak, orijinal güncellemeyi güncelleme ifadesindeki koşul olarak değiştirilerek yapın where id in temp_table.
Ve eşzamanlılığı sağlamak için, bu iki adımdan önce tabloyu kilitlemeniz ve ardından kilidi açmanız gerekir .
Yine, bu benim için çalışıyor, ile biten bir sorgu için limit 1, bu yüzden geçici bir tablo bile kullanmıyorum, bunun yerine ilkinin sonucunu saklamak için basit bir değişken select.
Her zaman sadece bir satırı güncelleyeceğimi ve kodun basit olduğunu bildiğim için bu yöntemi tercih ediyorum.
SET @uids := "";
UPDATE myf___ingtable
SET id = id
WHERE id < 5
AND ( SELECT @uids := CONCAT_WS(',', CAST(id AS CHAR CHARACTER SET utf8), @uids) );
SELECT @uids;
Kimliği CAST yapmak zorunda kaldım (neden bilmiyorum) ... ya da @uids içeriğini alamıyorum (bir blob idi) Btw Pomyk cevabı için çok teşekkürler!
Son güncellenen satırın kimliği, o satırı bulmak ve güncellemek için "updateQuery" de kullandığınız kimlik ile aynıdır. Bu yüzden, istediğiniz şekilde bu kimliği kaydedin (arayın).
last_insert_id()bağlıdır AUTO_INCREMENT, ancak son güncellenen kimlik değil.
Benim çözümüm, önce select komutuyla "id" (@uids) 'e karar verin ve ardından bu kimliği @uids ile güncelledikten sonra.
SET @uids := (SELECT id FROM table WHERE some = 0 LIMIT 1);
UPDATE table SET col = 1 WHERE id = @uids;SELECT @uids;
projemde çalıştı.
Yalnızca eklemeler yapıyorsanız ve aynı oturumdan bir tane istiyorsanız, peirix'in cevabına göre yapın. Değişiklikler yapıyorsanız, en son güncellenen girişi saklamak için veritabanı şemanızı değiştirmeniz gerekecektir.
Farklı bir oturumdan (yani şu anda çalışan PHP kodu tarafından yapılan değil, farklı bir isteğe yanıt olarak yapılan) son değişiklikten gelen kimliği istiyorsanız, bir TIMESTAMP sütunu, tablonuza last_modified ( bilgi için bkz. Http://dev.mysql.com/doc/refman/5.1/en/datetime.html ) adını verin ve ardından güncellediğinizde last_modified = CURRENT_TIME olarak ayarlayın.
Bunu ayarladıktan sonra, aşağıdaki gibi bir sorgu kullanabilirsiniz: SELECT id from table ORDER BY last_modified DESC LIMIT 1; en son değiştirilen satırı almak için.