Bagaimana cara mendapatkan ID dari baris terakhir yang diperbarui di MySQL menggunakan PHP?
UPDATE foo WHERE bar = 1; SELECT id FROM foo WHERE bar = 1
?
Bagaimana cara mendapatkan ID dari baris terakhir yang diperbarui di MySQL menggunakan PHP?
UPDATE foo WHERE bar = 1; SELECT id FROM foo WHERE bar = 1
?
Jawaban:
Saya telah menemukan jawaban untuk masalah ini :)
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;
EDIT oleh aefxx
Teknik ini dapat dikembangkan lebih lanjut untuk mengambil ID dari setiap baris yang dipengaruhi oleh pernyataan pembaruan:
SET @uids := null;
UPDATE footable
SET foo = 'bar'
WHERE fooid > 5
AND ( SELECT @uids := CONCAT_WS(',', fooid, @uids) );
SELECT @uids;
Ini akan mengembalikan string dengan semua ID yang diakhiri dengan koma.
WHERE
klausa, Anda cukup menggunakan WHERE
klausa yang sama dalam permintaan Anda berikutnyaSELECT id FROM footable WHERE fooid > 5
LAST_INSERT_ID()
dapat menerima argumen yang akan mengatur nilai yang dikembalikan oleh panggilan berikutnya ke LAST_INSERT_ID()
. Sebagai contoh: UPDATE table SET id=LAST_INSERT_ID(id), row='value' WHERE other_row='blah';
. Sekarang, SELECT LAST_INSERT_ID();
akan mengembalikan id yang diperbarui. Lihat jawaban newtover untuk lebih jelasnya.
UPDATE lastinsertid_test SET row='value' WHERE row='asd' AND LAST_INSERT_ID(id) OR LAST_INSERT_ID(0);
. Namun itu tidak mengambil beberapa id, jadi jawaban ini lebih unggul.
Hm, saya terkejut bahwa di antara jawaban saya tidak melihat solusi termudah.
Misalkan, item_id
adalah kolom identitas bilangan bulat dalam items
tabel dan Anda memperbarui baris dengan pernyataan berikut:
UPDATE items
SET qwe = 'qwe'
WHERE asd = 'asd';
Kemudian, untuk mengetahui baris terbaru yang terpengaruh tepat setelah pernyataan, Anda harus sedikit memperbarui pernyataan menjadi yang berikut:
UPDATE items
SET qwe = 'qwe',
item_id=LAST_INSERT_ID(item_id)
WHERE asd = 'asd';
SELECT LAST_INSERT_ID();
Jika Anda perlu memperbarui hanya baris yang benar-benar berubah, Anda harus menambahkan pembaruan bersyarat dari item_id melalui LAST_INSERT_ID memeriksa apakah data akan berubah di baris.
UPDATE items SET qwe = 'qwe' WHERE asd = 'asd' AND LAST_INSERT_ID(item_id); SELECT LAST_INSERT_ID();
Ini secara resmi sederhana tetapi sangat kontra-intuitif. Jika Anda melakukannya:
update users set status = 'processing' where status = 'pending'
limit 1
Ubah ke ini:
update users set status = 'processing' where status = 'pending'
and last_insert_id(user_id)
limit 1
Penambahan last_insert_id(user_id)
dalam where
klausa memberitahu MySQL untuk mengatur variabel internal ke ID dari baris yang ditemukan. Ketika Anda memberikan nilai last_insert_id(expr)
seperti ini, akhirnya mengembalikan nilai itu, yang dalam kasus ID seperti di sini selalu bilangan bulat positif dan karenanya selalu bernilai true, tidak pernah mengganggu klausa di mana. Ini hanya berfungsi jika beberapa baris benar-benar ditemukan, jadi ingatlah untuk memeriksa baris yang terpengaruh. Anda kemudian bisa mendapatkan ID dengan berbagai cara.
Anda dapat membuat urutan tanpa memanggil LAST_INSERT_ID (), tetapi utilitas menggunakan fungsi dengan cara ini adalah bahwa nilai ID dipertahankan di server sebagai nilai yang dihasilkan secara otomatis terakhir. Ini multi-user aman karena banyak klien dapat mengeluarkan pernyataan UPDATE dan mendapatkan nilai urutan mereka sendiri dengan pernyataan SELECT (atau mysql_insert_id ()), tanpa mempengaruhi atau dipengaruhi oleh klien lain yang menghasilkan nilai urutan mereka sendiri.
Mengembalikan nilai yang dihasilkan untuk kolom AUTO_INCREMENT oleh pernyataan INSERT atau UPDATE sebelumnya. Gunakan fungsi ini setelah Anda melakukan pernyataan INSERT ke dalam tabel yang berisi bidang AUTO_INCREMENT, atau telah menggunakan INSERT atau UPDATE untuk menetapkan nilai kolom dengan LAST_INSERT_ID (expr).
Alasan perbedaan antara LAST_INSERT_ID () dan mysql_insert_id () adalah bahwa LAST_INSERT_ID () dibuat mudah digunakan dalam skrip sementara mysql_insert_id () mencoba memberikan informasi yang lebih tepat tentang apa yang terjadi pada kolom AUTO_INCREMENT.
Melakukan pernyataan INSERT atau UPDATE menggunakan fungsi LAST_INSERT_ID () juga akan mengubah nilai yang dikembalikan oleh fungsi mysqli_insert_id ().
Menyatukan semuanya:
$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();
}
(FYI bahwa kelas DB ada di sini .)
Ini adalah metode yang sama dengan jawaban Salman A, tetapi inilah kode yang harus Anda lakukan.
Pertama, edit tabel Anda sehingga secara otomatis akan melacak setiap kali baris diubah. Hapus baris terakhir jika Anda hanya ingin tahu kapan sebuah baris pertama kali dimasukkan.
ALTER TABLE mytable
ADD lastmodified TIMESTAMP
DEFAULT CURRENT_TIMESTAMP
ON UPDATE CURRENT_TIMESTAMP;
Kemudian, untuk mengetahui baris terakhir yang diperbarui, Anda dapat menggunakan kode ini.
SELECT id FROM mytable ORDER BY lastmodified DESC LIMIT 1;
Semua kode ini diangkat dari MySQL vs PostgreSQL: Menambahkan Kolom 'Terakhir Dimodifikasi' ke Tabel dan Manual MySQL: Baris Pengurutan . Saya baru saja mengumpulkannya.
Pertanyaan:
$sqlQuery = "UPDATE
update_table
SET
set_name = 'value'
WHERE
where_name = 'name'
LIMIT 1;";
Fungsi PHP:
function updateAndGetId($sqlQuery)
{
mysql_query(str_replace("SET", "SET id = LAST_INSERT_ID(id),", $sqlQuery));
return mysql_insert_id();
}
Ini bekerja untuk saya;)
Lebih jauh ke Jawaban Di Atas Diterima
Untuk mereka yang bertanya-tanya tentang :=
&=
Perbedaan yang signifikan antara :=
dan =
, dan itu adalah yang :=
berfungsi sebagai operator penugasan variabel di mana saja, sementara =
hanya berfungsi seperti itu dalam pernyataan SET, dan merupakan operator perbandingan di mana pun.
Jadi SELECT @var = 1 + 1;
akan meninggalkan @var
tidak berubah dan mengembalikan boolean (1 atau 0 tergantung pada nilai saat ini dari @var), sementara SELECT @var := 1 + 1;
akan berubah @var
menjadi 2 , dan mengembalikan 2 .
[Sumber]
Hei, aku hanya butuh trik seperti itu - aku menyelesaikannya dengan cara yang berbeda, mungkin itu akan berhasil untukmu. Perhatikan ini bukan solusi yang dapat diskalakan dan akan sangat buruk untuk set data besar.
Pisahkan permintaan Anda menjadi dua bagian -
pertama, pilih id dari baris yang ingin Anda perbarui dan simpan di tabel sementara.
kedua, lakukan pembaruan asli dengan kondisi dalam pernyataan pembaruan diubah menjadi where id in temp_table
.
Dan untuk memastikan konkurensi, Anda perlu mengunci tabel sebelum dua langkah ini dan kemudian lepaskan kunci di akhir.
Sekali lagi, ini bekerja untuk saya, untuk kueri yang berakhir dengan limit 1
, jadi saya bahkan tidak menggunakan tabel temp, tetapi hanya sebuah variabel untuk menyimpan hasil yang pertama select
.
Saya lebih suka metode ini karena saya tahu saya akan selalu memperbarui hanya satu baris, dan kodenya mudah.
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;
Saya harus CAST id (tidak tahu kenapa) ... atau saya tidak bisa mendapatkan konten @ids (itu adalah gumpalan) Btw banyak terima kasih atas jawaban Pomyk!
ID dari baris yang terakhir diperbarui adalah ID yang sama yang Anda gunakan di 'updateQuery' untuk menemukan & memperbarui baris itu. Jadi, simpan saja (panggil) ID itu di yang Anda inginkan.
last_insert_id()
tergantung pada AUTO_INCREMENT
, tetapi ID yang terakhir diperbarui tidak.
Solusi saya adalah, pertama-tama tentukan "id" (@uids) dengan perintah pilih dan setelah perbarui id ini dengan @uids.
SET @uids := (SELECT id FROM table WHERE some = 0 LIMIT 1);
UPDATE table SET col = 1 WHERE id = @uids;SELECT @uids;
itu berhasil pada proyek saya.
Jika Anda hanya melakukan penyisipan, dan ingin satu dari sesi yang sama, lakukan sesuai jawaban peirix. Jika Anda melakukan modifikasi, Anda perlu memodifikasi skema basis data Anda untuk menyimpan entri mana yang terakhir diperbarui.
Jika Anda ingin id dari modifikasi terakhir, yang mungkin berasal dari sesi yang berbeda (yaitu bukan yang baru saja dilakukan oleh kode PHP yang berjalan saat ini, tetapi yang dilakukan sebagai tanggapan atas permintaan yang berbeda), Anda dapat menambahkan Kolom TIMESTAMP ke tabel Anda disebut last_modified (lihat http://dev.mysql.com/doc/refman/5.1/en/datetime.html untuk informasi), dan kemudian ketika Anda memperbarui, atur last_modified = CURRENT_TIME.
Setelah menetapkan ini, Anda dapat menggunakan kueri seperti: SELECT id FROM table ORDER BY last_modified DESC LIMIT 1; untuk mendapatkan baris yang paling baru dimodifikasi.