Banyak Pembaruan di MySQL


388

Saya tahu bahwa Anda dapat memasukkan beberapa baris sekaligus, apakah ada cara untuk memperbarui beberapa baris sekaligus (seperti dalam, dalam satu permintaan) di MySQL?

Sunting: Misalnya saya punya yang berikut ini

Name   id  Col1  Col2
Row1   1    6     1
Row2   2    2     3
Row3   3    9     5
Row4   4    16    8

Saya ingin menggabungkan semua Pembaruan berikut ke dalam satu permintaan

UPDATE table SET Col1 = 1 WHERE id = 1;
UPDATE table SET Col1 = 2 WHERE id = 2;
UPDATE table SET Col2 = 3 WHERE id = 3;
UPDATE table SET Col1 = 10 WHERE id = 4;
UPDATE table SET Col2 = 12 WHERE id = 4;

Jawaban:


652

Ya, itu mungkin - Anda dapat menggunakan INSERT ... ON DUPLICATE KEY UPDATE.

Menggunakan contoh Anda:

INSERT INTO table (id,Col1,Col2) VALUES (1,1,1),(2,2,3),(3,9,3),(4,10,12)
ON DUPLICATE KEY UPDATE Col1=VALUES(Col1),Col2=VALUES(Col2);

22
Jika tidak ada duplikat maka saya tidak ingin baris itu dimasukkan. apa yang harus saya lakukan? karena saya mengambil informasi dari situs lain yang mengelola tabel dengan id. Saya memasukkan nilai sehubungan dengan id itu. jika situs memiliki catatan baru maka saya hanya akan memasukkan id dan menghitung kecuali semua informasi lainnya. jika dan hanya jika ada entri untuk id maka itu harus memperbarui lain itu harus dilewati. apa yang harus saya lakukan?
Jayapal Chandran

33
Catatan: jawaban ini juga menganggap ID adalah kunci utama
JM4

11
@JayapalChandran Anda harus menggunakan INSERT IGNORE bersama dengan ON DUPLICATE KEY UPDATE. dev.mysql.com/doc/refman/5.5/en/insert.html
Haralan Dobrev

16
@HaralanDobrev Menggunakan INSERT IGNORE masih menyisipkan catatan yang tidak digandakan. yang ingin dihindari Jayapal. INSERT IGNORE mengubah kesalahan menjadi peringatan :( stackoverflow.com/questions/548541/…
Takehiro Adachi

2
Jawaban ini menganggap ID adalah kunci unik (bisa utama seperti kata orang lain) tetapi yang lebih penting diasumsikan tidak ada kunci unik lainnya. Jika ada, itu bisa melempar kunci pas dalam karya.
Steve Horvath

130

Karena Anda memiliki nilai dinamis, Anda perlu menggunakan IF atau KASUS untuk kolom yang akan diperbarui. Agak jelek, tapi itu harusnya berhasil.

Dengan menggunakan contoh Anda, Anda bisa melakukannya seperti:

Tabel UPDATE SET Col1 = KASUS id 
                          KAPAN 1 KEMUDIAN 1 
                          KAPAN 2 KEMUDIAN 2 
                          KAPAN 4 KEMUDIAN 10 
                          ELSE Col1 
                        AKHIR, 
                 Col2 = KASUS id 
                          KAPAN 3 KEMUDIAN 3 
                          KAPAN 4 KEMUDIAN 12 
                          ELSE Col2 
                        AKHIR
             WHERE id IN (1, 2, 3, 4);

mungkin tidak begitu cantik untuk menulis untuk pembaruan dinamis tetapi tampilan menarik pada fungsi casing ...
me_

1
@ user2536953, ini bisa bagus untuk pembaruan dinamis juga. Sebagai contoh, saya menggunakan solusi itu dalam loop di php:$commandTxt = 'UPDATE operations SET chunk_finished = CASE id '; foreach ($blockOperationChecked as $operationID => $operationChecked) $commandTxt .= " WHEN $operationID THEN $operationChecked "; $commandTxt .= 'ELSE id END WHERE id IN ('.implode(', ', array_keys(blockOperationChecked )).');';
Boolean_Type

86

Pertanyaannya sudah lama, namun saya ingin memperluas topik dengan jawaban lain.

Maksud saya adalah, cara termudah untuk mencapainya adalah dengan membungkus beberapa kueri dengan transaksi. Jawaban yang diterima INSERT ... ON DUPLICATE KEY UPDATEadalah hack yang bagus, tetapi orang harus menyadari kelemahan dan keterbatasannya:

  • Seperti yang dikatakan, jika Anda meluncurkan kueri dengan baris yang kunci utamanya tidak ada di tabel, kueri menyisipkan catatan "setengah-panggang" baru. Mungkin itu bukan yang Anda inginkan
  • Jika Anda memiliki tabel dengan bidang bukan nol tanpa nilai default dan tidak ingin menyentuh bidang ini dalam kueri, Anda akan mendapatkan "Field 'fieldname' doesn't have a default value"peringatan MySQL bahkan jika Anda tidak memasukkan satu baris sama sekali. Ini akan membuat Anda mendapat masalah, jika Anda memutuskan untuk ketat dan mengubah peringatan mysql menjadi pengecualian runtime di aplikasi Anda.

Saya membuat beberapa tes kinerja untuk tiga varian yang disarankan, termasuk INSERT ... ON DUPLICATE KEY UPDATEvarian, varian dengan klausa "case / when / then" dan pendekatan naif dengan transaksi. Anda dapat memperoleh kode python dan hasil di sini . Kesimpulan keseluruhan adalah bahwa varian dengan pernyataan kasus ternyata dua kali lebih cepat dari dua varian lainnya, tetapi cukup sulit untuk menulis kode yang benar dan aman untuknya, jadi saya pribadi tetap menggunakan pendekatan yang paling sederhana: menggunakan transaksi.

Sunting: Temuan Dakusan membuktikan bahwa estimasi kinerja saya tidak cukup valid. Silakan lihat jawaban ini untuk penelitian lain yang lebih rumit.


Menggunakan transaksi, tip yang sangat bagus (dan sederhana)!
mTorres

Bagaimana jika tabel saya bukan Tipe InnoDB?
TomeeNS

1
Bisakah seseorang memberikan tautan ke transaksi apa yang terlihat seperti ini? Dan / atau kode untuk kode injeksi-aman untuk varian dengan pernyataan kasus?
François M.

1
Saya menemukan informasi yang diberikan tentang kecepatan dalam posting ini salah. Saya menulisnya di posting di bawah ini. stackoverflow.com/questions/3432/multiple-updates-in-mysql/…
Dakusan

1
@ Dakusan, jawaban yang bagus. Terima kasih banyak untuk memperluas, mengomentari, dan memperbaiki hasil saya.
Roman Imankulov

72

Tidak yakin mengapa opsi lain yang bermanfaat belum disebutkan:

UPDATE my_table m
JOIN (
    SELECT 1 as id, 10 as _col1, 20 as _col2
    UNION ALL
    SELECT 2, 5, 10
    UNION ALL
    SELECT 3, 15, 30
) vals ON m.id = vals.id
SET col1 = _col1, col2 = _col2;

4
Ini yang terbaik. Terutama jika Anda menarik nilai untuk pembaruan dari permintaan SQL lain seperti yang saya lakukan.
v010dya

1
Ini bagus untuk pembaruan di atas meja dengan sejumlah besar kolom. Saya mungkin akan sering menggunakan kueri ini. Terima kasih!
Casper Wilkes

Saya sudah mencoba jenis permintaan ini. Tetapi ketika catatan mencapai 30k Batas server berhenti. Apakah ada solusi lain?
Bhavin Chauhan

Ini terlihat hebat. Saya akan mencoba menggabungkan ini dengan klausa WHERE di mana kunci utama tidak diperbarui, tetapi digunakan untuk mengidentifikasi kolom yang akan diubah.
nl-x

@ BhavinChauhan Sudahkah Anda mencoba menggunakan tabel sementara alih-alih memilih bergabung untuk menghindari masalah?
nl-x

41

Semua hal berikut ini berlaku untuk InnoDB.

Saya merasa mengetahui kecepatan dari 3 metode yang berbeda itu penting.

Ada 3 metode:

  1. INSERT: INSERT dengan ON DUPLICATE KEY UPDATE
  2. TRANSAKSI: Di mana Anda melakukan pembaruan untuk setiap catatan dalam suatu transaksi
  3. KASUS: Di mana Anda case / kapan untuk setiap catatan yang berbeda dalam UPDATE

Saya baru saja menguji ini, dan metode INSERT 6,7x lebih cepat untuk saya daripada metode TRANSAKSI. Saya mencoba serangkaian 3.000 dan 30.000 baris.

Metode TRANSACTION masih harus menjalankan setiap permintaan secara individual, yang membutuhkan waktu, meskipun batch hasil dalam memori, atau sesuatu, saat mengeksekusi. Metode TRANSACTION juga cukup mahal untuk replikasi dan log permintaan.

Lebih buruk lagi, metode CASE adalah 41.1x lebih lambat dari metode INSERT dengan 30.000 catatan (6.1x lebih lambat dari TRANSACTION). Dan 75x lebih lambat di MyISAM. Metode INSERT dan CASE mencapai titik ~ 1.000 catatan Bahkan pada 100 catatan, metode KASUS BARELY lebih cepat.

Jadi secara umum, saya merasa metode INSERT adalah yang terbaik dan termudah untuk digunakan. Kueri lebih kecil dan lebih mudah dibaca dan hanya mengambil 1 kueri tindakan. Ini berlaku untuk InnoDB dan MyISAM.

Barang bonus:

Solusi untuk INSERT masalah non-default-bidang adalah untuk mematikan sementara mode SQL yang relevan: SET SESSION sql_mode=REPLACE(REPLACE(@@SESSION.sql_mode,"STRICT_TRANS_TABLES",""),"STRICT_ALL_TABLES",""). Pastikan untuk menyimpan yang sql_modepertama jika Anda berencana untuk mengembalikannya.

Adapun komentar lain saya telah melihat bahwa mengatakan auto_increment naik menggunakan metode INSERT, ini tampaknya menjadi kasus di InnoDB, tetapi bukan MyISAM.

Kode untuk menjalankan tes adalah sebagai berikut. Ini juga menampilkan file .SQL untuk menghapus overhead penerjemah php

<?
//Variables
$NumRows=30000;

//These 2 functions need to be filled in
function InitSQL()
{

}
function RunSQLQuery($Q)
{

}

//Run the 3 tests
InitSQL();
for($i=0;$i<3;$i++)
    RunTest($i, $NumRows);

function RunTest($TestNum, $NumRows)
{
    $TheQueries=Array();
    $DoQuery=function($Query) use (&$TheQueries)
    {
        RunSQLQuery($Query);
        $TheQueries[]=$Query;
    };

    $TableName='Test';
    $DoQuery('DROP TABLE IF EXISTS '.$TableName);
    $DoQuery('CREATE TABLE '.$TableName.' (i1 int NOT NULL AUTO_INCREMENT, i2 int NOT NULL, primary key (i1)) ENGINE=InnoDB');
    $DoQuery('INSERT INTO '.$TableName.' (i2) VALUES ('.implode('), (', range(2, $NumRows+1)).')');

    if($TestNum==0)
    {
        $TestName='Transaction';
        $Start=microtime(true);
        $DoQuery('START TRANSACTION');
        for($i=1;$i<=$NumRows;$i++)
            $DoQuery('UPDATE '.$TableName.' SET i2='.(($i+5)*1000).' WHERE i1='.$i);
        $DoQuery('COMMIT');
    }

    if($TestNum==1)
    {
        $TestName='Insert';
        $Query=Array();
        for($i=1;$i<=$NumRows;$i++)
            $Query[]=sprintf("(%d,%d)", $i, (($i+5)*1000));
        $Start=microtime(true);
        $DoQuery('INSERT INTO '.$TableName.' VALUES '.implode(', ', $Query).' ON DUPLICATE KEY UPDATE i2=VALUES(i2)');
    }

    if($TestNum==2)
    {
        $TestName='Case';
        $Query=Array();
        for($i=1;$i<=$NumRows;$i++)
            $Query[]=sprintf('WHEN %d THEN %d', $i, (($i+5)*1000));
        $Start=microtime(true);
        $DoQuery("UPDATE $TableName SET i2=CASE i1\n".implode("\n", $Query)."\nEND\nWHERE i1 IN (".implode(',', range(1, $NumRows)).')');
    }

    print "$TestName: ".(microtime(true)-$Start)."<br>\n";

    file_put_contents("./$TestName.sql", implode(";\n", $TheQueries).';');
}

1
Anda sedang melakukan pekerjaan TUHAN di sini;) Sangat dihargai.
cabai

Menguji beberapa kinerja antara GoLang dan PHP, menggunakan baris 40k pada MariaDB, saya mendapatkan 2 detik pada PHP dan lebih dari 6 detik pada golang .... Ya, saya selalu diberitahu bahwa GoLang akan berjalan lebih cepat daripada PHP !!! SO, saya mulai bertanya-tanya bagaimana cara meningkatkan kinerja ... Menggunakan INSERT ... PADA UPDATE KUNCI DUPLICATE ... Saya mendapat 0,74 detik di Golang dan 0,86 detik di PHP !!!!
Diego Favero

1
Inti dari kode saya adalah membatasi hasil waktu hanya untuk pernyataan SQL, dan bukan kode untuk bahasa atau perpustakaan. GoLang dan PHP adalah 2 bahasa yang sepenuhnya terpisah yang dimaksudkan untuk hal-hal yang sama sekali berbeda. PHP dimaksudkan untuk lingkungan skrip yang dijalankan tunggal pada satu utas dengan sebagian besar pengumpulan sampah terbatas dan pasif. GoLang dimaksudkan untuk aplikasi kompilasi yang berjalan lama dengan pengumpulan sampah yang agresif dan multithreading sebagai salah satu fitur bahasa utama. Mereka hampir tidak bisa berbeda dalam hal fungsi dan alasan bahasa. [Lanjutan]
Dakusan

Jadi ketika menjalankan tes Anda, pastikan untuk membatasi pengukuran kecepatan hanya untuk fungsi "Permintaan" panggilan untuk pernyataan SQL. Membandingkan dan mengoptimalkan bagian lain dari kode sumber yang tidak sepenuhnya panggilan kueri adalah seperti membandingkan apel dan jeruk. Jika Anda membatasi hasil Anda untuk ini (memiliki string dikompilasi dan siap untuk pergi) maka hasilnya harus sangat mirip. Perbedaan apa pun pada titik itu adalah kesalahan pustaka SQL bahasa, dan tidak harus bahasa itu sendiri. Menurut pendapat saya, solusi INSERT ON DUPLICATE adalah dan akan selalu menjadi pilihan terbaik. [Lanjutkan]
Dakusan

Adapun komentar Anda tentang GoLang menjadi lebih cepat, itu adalah pernyataan yang sangat luas yang tidak memperhitungkan banyak peringatan atau nuansa bahasa dan desain mereka. Java adalah bahasa yang ditafsirkan, tetapi saya menemukan 15 tahun yang lalu itu sebenarnya hampir dapat mencocokkan (dan mungkin bahkan kadang-kadang mengalahkan) C dalam kecepatan dalam skenario tertentu. Dan C adalah bahasa yang dikompilasi, dan yang paling umum dari bahasa sistem tingkat terendah, selain assembler. Saya sangat menyukai apa yang dilakukan GoLang dan tentu saja memiliki kekuatan dan kelancaran untuk menjadi salah satu sistem yang paling umum dan dioptimalkan [Lanjut]
Dakusan

9

Gunakan tabel sementara

// Reorder items
function update_items_tempdb(&$items)
{
    shuffle($items);
    $table_name = uniqid('tmp_test_');
    $sql = "CREATE TEMPORARY TABLE `$table_name` ("
        ."  `id` int(10) unsigned NOT NULL AUTO_INCREMENT"
        .", `position` int(10) unsigned NOT NULL"
        .", PRIMARY KEY (`id`)"
        .") ENGINE = MEMORY";
    query($sql);
    $i = 0;
    $sql = '';
    foreach ($items as &$item)
    {
        $item->position = $i++;
        $sql .= ($sql ? ', ' : '')."({$item->id}, {$item->position})";
    }
    if ($sql)
    {
        query("INSERT INTO `$table_name` (id, position) VALUES $sql");
        $sql = "UPDATE `test`, `$table_name` SET `test`.position = `$table_name`.position"
            ." WHERE `$table_name`.id = `test`.id";
        query($sql);
    }
    query("DROP TABLE `$table_name`");
}

8
UPDATE table1, table2 SET table1.col1='value', table2.col1='value' WHERE table1.col3='567' AND table2.col6='567'

Ini seharusnya bekerja untukmu.

Ada referensi dalam manual MySQL untuk beberapa tabel.


6

Mengapa tidak ada yang menyebutkan banyak pernyataan dalam satu permintaan ?

Di php, Anda menggunakan multi_querymetode instance mysqli.

Dari manual php

MySQL secara opsional memungkinkan memiliki banyak pernyataan dalam satu string pernyataan. Mengirim beberapa pernyataan sekaligus mengurangi round-trip klien-server tetapi membutuhkan penanganan khusus.

Berikut adalah hasil perbandingan dengan 3 metode lainnya dalam memperbarui 30.000 mentah. Kode dapat ditemukan di sini yang didasarkan pada jawaban dari @Dakusan

Transaksi: 5.5194580554962
Masukkan: 0.20669293403625
Kasus: 16.474853992462
Multi: 0.0412278175354

Seperti yang Anda lihat, permintaan beberapa pernyataan lebih efisien daripada jawaban tertinggi.

Jika Anda mendapatkan pesan kesalahan seperti ini:

PHP Warning:  Error while sending SET_OPTION packet

Anda mungkin perlu menambah max_allowed_packetfile config di mysql yang ada di mesin saya /etc/mysql/my.cnfdan kemudian restart mysqld.


Semua perbandingan di bawah ini dijalankan terhadap tes INSERT. Saya hanya menjalankan tes dalam kondisi yang sama dan, tanpa transaksi, itu 145x lebih lambat pada 300 baris dan 753x lebih lambat untuk 3000 baris. Saya awalnya mulai dengan 30.000 baris, tetapi saya pergi untuk membuat makan siang dan kembali, dan masih berjalan. Ini masuk akal karena menjalankan kueri individual dan membilas masing-masing ke basis data secara individual akan sangat mahal. Apalagi dengan replikasi. Mengaktifkan transaksi membuat perbedaan besar. Pada 3.000 baris, dibutuhkan 1.5x lebih banyak dan 30.000 baris 2.34x . [lanjutan]
Dakusan

Tetapi Anda benar tentang hal itu menjadi cepat (dengan transaksi). Baik pada 3.000 dan 30.000 baris itu lebih cepat daripada segalanya kecuali metode INSERT. Sama sekali tidak ada cara Anda akan mendapatkan hasil yang lebih baik dari menjalankan 1 permintaan dari 30.000 permintaan, bahkan jika mereka dikelompokkan dalam panggilan API MySQL khusus. Berjalan hanya 300 baris, itu JAUH lebih cepat dari semua metode lain (yang mengejutkan saya), yang mengikuti tentang kurva grafik yang sama dengan metode CASE. Ini menjadi lebih cepat dapat dijelaskan dengan 2 cara. Yang pertama adalah bahwa metode INSERT pada dasarnya selalu menyisipkan 2 baris karena "ON DUPLICATE KEY [cont]
Dakusan

UPDATE "menyebabkan kedua" INSERT "Dan" UPDATE ".Yang lain adalah bahwa itu kurang bekerja dalam prosesor SQL untuk hanya mengedit 1 baris sekaligus karena indeks pencarian. Saya tidak yakin bagaimana Anda mendapatkan hasil yang berbeda dari saya, tetapi tes tambahan Anda terlihat solid. Saya sebenarnya bahkan tidak yakin bagaimana replikasi akan menangani panggilan ini. Ini juga hanya akan berfungsi untuk melakukan panggilan UPDATE. Panggilan Insert akan SELALU tercepat dengan permintaan INSERT tunggal.
Dakusan

Saya sedang melakukan 300 PEMBARUAN sekaligus di atas meja untuk memperbaiki kesalahan dalam for loop yang membutuhkan 41 detik. Menempatkan kueri UPDATE yang sama menjadi satu $mysqli->multi_query($sql)membutuhkan waktu "0" detik. Namun, permintaan berikutnya gagal, menyebabkan saya menjadikan ini "program" yang terpisah.
Chris K

Terima kasih. Mampu memperbarui sekitar 5k baris (tidak menguji lebih banyak) dalam satu menit menggunakan multi kueri. Jika seseorang mencari solusi PDO: stackoverflow.com/questions/6346674/…
Scofield

3

Ada pengaturan yang dapat Anda ubah yang disebut 'pernyataan multi' yang menonaktifkan 'mekanisme keselamatan' MySQL yang diterapkan untuk mencegah (lebih dari satu) perintah injeksi. Khas untuk implementasi MySQL yang 'brilian', ini juga mencegah pengguna melakukan kueri yang efisien.

Di sini ( http://dev.mysql.com/doc/refman/5.1/en/mysql-set-server-option.html ) adalah beberapa info tentang implementasi C dari pengaturan.

Jika Anda menggunakan PHP, Anda dapat menggunakan mysqli untuk melakukan banyak pernyataan (saya pikir php telah dikirimkan dengan mysqli untuk sementara waktu sekarang)

$con = new mysqli('localhost','user1','password','my_database');
$query = "Update MyTable SET col1='some value' WHERE id=1 LIMIT 1;";
$query .= "UPDATE MyTable SET col1='other value' WHERE id=2 LIMIT 1;";
//etc
$con->multi_query($query);
$con->close();

Semoga itu bisa membantu.


4
Ini sama dengan mengirim pertanyaan secara terpisah. Satu-satunya perbedaan adalah bahwa Anda mengirim semuanya dalam satu paket jaringan, tetapi UPDATE akan tetap diproses sebagai permintaan terpisah. Lebih baik membungkusnya dalam satu transaksi, maka perubahan akan dilakukan ke tabel sekaligus.
Marki555

3
Bagaimana cara membungkusnya dalam satu transaksi? Tolong tunjukkan pada kami.
TomeeNS

@TomeeNS Gunakan mysqli::begin_transaction(..)sebelum mengirim kueri dan mysql::commit(..)sesudahnya. Atau gunakan pernyataan START TRANSACTIONpertama dan COMMITterakhir dalam kueri itu sendiri.
Juha Palomäki

3

Anda bisa alias tabel yang sama untuk memberi Anda id yang ingin Anda masukkan (jika Anda melakukan pembaruan baris-demi-baris:

UPDATE table1 tab1, table1 tab2 -- alias references the same table
SET 
col1 = 1
,col2 = 2
. . . 
WHERE 
tab1.id = tab2.id;

Selain itu, tampak jelas bahwa Anda juga dapat memperbarui dari tabel lain juga. Dalam hal ini, pembaruan berfungsi ganda sebagai pernyataan "SELECT", memberi Anda data dari tabel yang Anda tentukan. Anda secara eksplisit menyatakan dalam kueri Anda nilai-nilai pembaruan sehingga, tabel kedua tidak terpengaruh.


2

Anda juga mungkin tertarik menggunakan gabungan pada pembaruan, yang juga dimungkinkan.

Update someTable Set someValue = 4 From someTable s Inner Join anotherTable a on s.id = a.id Where a.id = 4
-- Only updates someValue in someTable who has a foreign key on anotherTable with a value of 4.

Sunting: Jika nilai yang Anda perbarui tidak berasal dari tempat lain dalam database, Anda harus mengeluarkan beberapa permintaan pembaruan.


1

Dan sekarang cara mudah

update speed m,
    (select 1 as id, 20 as speed union
     select 2 as id, 30 as speed union
     select 99 as id, 10 as speed
        ) t
set m.speed = t.speed where t.id=m.id

-1

menggunakan

REPLACE INTO`table` VALUES (`id`,`col1`,`col2`) VALUES
(1,6,1),(2,2,3),(3,9,5),(4,16,8);

Tolong dicatat:

  • id harus menjadi kunci unik utama
  • jika Anda menggunakan kunci asing untuk referensi tabel, REPLACE menghapus lalu menyisipkan, jadi ini dapat menyebabkan kesalahan

-3

Berikut ini akan memperbarui semua baris dalam satu tabel

Update Table Set
Column1 = 'New Value'

Yang berikutnya akan memperbarui semua baris di mana nilai Column2 lebih dari 5

Update Table Set
Column1 = 'New Value'
Where
Column2 > 5

Ada semua contoh Unkwntech untuk memperbarui lebih dari satu tabel

UPDATE table1, table2 SET
table1.col1 = 'value',
table2.col1 = 'value'
WHERE
table1.col3 = '567'
AND table2.col6='567'

-3

Ya .. itu mungkin menggunakan INSERT ON DUPLICATE KEY UPDATE pernyataan sql .. sintaks: INSERT INTO table_name (a, b, c) VALUES (1,2,3), (4,5,6) ON DUPLICATE KEY UPDATE a = VALUES (a), b = VALUES (b), c = VALUES (c)


-5
UPDATE tableName SET col1='000' WHERE id='3' OR id='5'

Ini harus mencapai apa yang Anda cari. Cukup tambahkan lebih banyak id. Saya sudah mengujinya.


-7
UPDATE `your_table` SET 

`something` = IF(`id`="1","new_value1",`something`), `smth2` = IF(`id`="1", "nv1",`smth2`),
`something` = IF(`id`="2","new_value2",`something`), `smth2` = IF(`id`="2", "nv2",`smth2`),
`something` = IF(`id`="4","new_value3",`something`), `smth2` = IF(`id`="4", "nv3",`smth2`),
`something` = IF(`id`="6","new_value4",`something`), `smth2` = IF(`id`="6", "nv4",`smth2`),
`something` = IF(`id`="3","new_value5",`something`), `smth2` = IF(`id`="3", "nv5",`smth2`),
`something` = IF(`id`="5","new_value6",`something`), `smth2` = IF(`id`="5", "nv6",`smth2`) 

// Anda hanya membangunnya seperti php

$q = 'UPDATE `your_table` SET ';

foreach($data as $dat){

  $q .= '

       `something` = IF(`id`="'.$dat->id.'","'.$dat->value.'",`something`), 
       `smth2` = IF(`id`="'.$dat->id.'", "'.$dat->value2.'",`smth2`),';

}

$q = substr($q,0,-1);

Jadi, Anda dapat memperbarui tabel lubang dengan satu permintaan


Aku tidak downvote, tapi saya pikir keberatan adalah untuk melakukan set, ketika itu tidak diperlukan (dan Anda masih melakukannya, ketika Anda sedang mengatur somethinguntuk something)
v010dya
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.