Wiele aktualizacji w MySQL

388

Wiem, że możesz wstawić wiele wierszy jednocześnie. Czy istnieje sposób na aktualizację wielu wierszy jednocześnie (jak w jednym zapytaniu) w MySQL?

Edycja: Na przykład mam następujące

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

Chcę połączyć wszystkie następujące aktualizacje w jedno zapytanie

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;
Teifion
źródło

Odpowiedzi:

651

Tak, to możliwe - możesz użyć INSERT ... NA DUPLIKACIE KLUCZOWEJ AKTUALIZACJI.

Na twoim przykładzie:

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);
Michiel de Mare
źródło
22
Jeśli nie ma duplikatów, nie chcę, aby ten wiersz został wstawiony. co powinienem zrobić? ponieważ pobieram informacje z innej witryny, która utrzymuje tabele z identyfikatorami. Wstawiam wartości w odniesieniu do tego identyfikatora. jeśli strona ma nowe rekordy, w końcu wstawię tylko identyfikatory i policzę oprócz wszystkich innych informacji. jeśli i tylko jeśli istnieje wpis dla identyfikatora, powinien on zaktualizować, w przeciwnym razie powinien pominąć. co powinienem zrobić?
Jayapal Chandran
33
Uwaga: ta odpowiedź zakłada również, że identyfikator jest kluczem podstawowym
JM4
11
@JayapalChandran należy używać INSERT IGNORE razem z ON DUPLICATE KEY UPDATE. dev.mysql.com/doc/refman/5.5/en/insert.html
Haralan Dobrev
16
@HaralanDobrev Korzystanie z INSERT IGNORE nadal wstawia niepowielone rekordy. czego Jayapal chciał uniknąć. INSERT IGNORE po prostu zamienia wszelkie błędy w ostrzeżenia :( stackoverflow.com/questions/548541/…
Takehiro Adachi
2
Ta odpowiedź zakłada, że ​​identyfikator jest unikalnym kluczem (może być podstawowym, jak powiedzieli inni), ale co ważniejsze, zakłada, że ​​nie ma innych unikalnych kluczy. Jeśli są, może rzucić kluczem w prace.
Steve Horvath,
129

Ponieważ masz wartości dynamiczne, musisz użyć IF lub CASE, aby kolumny zostały zaktualizowane. Robi się trochę brzydki, ale powinien działać.

Korzystając z Twojego przykładu, możesz to zrobić w następujący sposób:

UPDATE table SET Col1 = CASE id 
                          KIEDY 1, a następnie 1 
                          KIEDY 2 NASTĘPNIE 2 
                          KIEDY 4 NIŻ 10 
                          ELSE Col1 
                        KONIEC, 
                 Kol2 = identyfikator CASE 
                          KIEDY 3, A potem 3 
                          KIEDY 4, NASTĘPNIE 12 
                          ELSE Col2 
                        KONIEC
             GDZIE ID IN (1, 2, 3, 4);
Harrison Fisk
źródło
może nie tak ładnie pisać do dynamicznej aktualizacji, ale ciekawe spojrzenie na funkcjonalność obudowy ...
me_
1
@ user2536953, może być również przydatne do dynamicznej aktualizacji. Na przykład użyłem tego rozwiązania w pętli w 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

Pytanie jest stare, ale chciałbym rozszerzyć temat o inną odpowiedź.

Chodzi mi o to, że najprostszym sposobem na osiągnięcie tego jest po prostu zawarcie wielu zapytań transakcją. Przyjęta odpowiedź INSERT ... ON DUPLICATE KEY UPDATEto niezły hack, ale należy pamiętać o jej wadach i ograniczeniach:

  • Jak powiedziano, jeśli zdarzy się, że uruchomisz zapytanie z wierszami, których kluczy podstawowych nie ma w tabeli, zapytanie wstawi nowe rekordy „na wpół wypalone”. Prawdopodobnie nie tego chcesz
  • Jeśli masz tabelę z niepustym polem bez wartości domyślnej i nie chcesz dotykać tego pola w zapytaniu, otrzymasz "Field 'fieldname' doesn't have a default value"ostrzeżenie MySQL, nawet jeśli w ogóle nie wstawisz jednego wiersza. Wpadniesz w kłopoty, jeśli zdecydujesz się zachować surowość i zmienisz ostrzeżenia mysql w wyjątki czasu wykonywania w swojej aplikacji.

Przeprowadziłem kilka testów wydajności dla trzech sugerowanych wariantów, w tym INSERT ... ON DUPLICATE KEY UPDATEwariantu, wariantu z klauzulą ​​„przypadek / kiedy / wtedy” i naiwnego podejścia do transakcji. Możesz pobrać kod python i wyniki tutaj . Ogólny wniosek jest taki, że wariant z instrukcją case okazuje się dwa razy szybszy niż dwa inne warianty, ale dość trudno jest napisać dla niego poprawny i bezpieczny dla iniekcji kod, więc ja osobiście trzymam się najprostszego podejścia: korzystania z transakcji.

Edycja: Ustalenia Dakusana dowodzą, że moje oszacowania wydajności nie są całkiem poprawne. Zapoznaj się z tą odpowiedzią na kolejne, bardziej szczegółowe badania.

Roman Imankulov
źródło
Korzystając z transakcji, bardzo miła (i prosta) wskazówka!
mTorres
Co jeśli moje tabele nie są typu InnoDB?
TomeeNS
1
Czy ktoś może podać link do tego, jak wyglądają takie transakcje? I / lub kod bezpiecznego dla iniekcji kodu dla wariantu z instrukcją case?
François M.,
1
Uważam, że informacje o prędkości w tym poście są fałszywe. Napisałem o tym w poniższym poście. stackoverflow.com/questions/3432/multiple-updates-in-mysql/…
Dakusan
1
@Dakusan, świetna odpowiedź. Bardzo dziękuję za rozszerzenie, komentowanie i naprawianie moich wyników.
Roman Imankulov
72

Nie jestem pewien, dlaczego nie wymieniono jeszcze jednej przydatnej opcji:

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;
Newtover
źródło
4
To jest najlepszy. Zwłaszcza jeśli pobierasz wartości do aktualizacji z innego zapytania SQL, tak jak ja.
v010dya
1
To było świetne dla aktualizacji na stole z ogromną ilością kolumn. Prawdopodobnie w przyszłości będę często używać tego zapytania. Dzięki!
Casper Wilkes,
Próbowałem tego typu zapytania. Ale gdy rekordy osiągną 30 000, serwer granic przestał działać. Czy jest jakieś inne rozwiązanie?
Bhavin Chauhan
To wygląda świetnie. Spróbuję połączyć to z klauzulą ​​WHERE, w której klucze podstawowe nie są aktualizowane, ale służą do identyfikacji kolumn do zmiany.
nl-x
@BhavinChauhan Czy próbowałeś użyć tabeli tymczasowej zamiast opcji Join-Select w celu obejścia problemu?
nl-x
41

Wszystkie poniższe informacje dotyczą InnoDB.

Czuję, że znajomość prędkości 3 różnych metod jest ważna.

Istnieją 3 metody:

  1. INSERT: INSERT z ON DUPLICATE KEY UPDATE
  2. TRANSAKCJA: W przypadku dokonywania aktualizacji dla każdego rekordu w ramach transakcji
  3. PRZYPADEK: w którym masz przypadek / kiedy dla każdego innego rekordu w ramach AKTUALIZACJI

Właśnie to przetestowałem, a metoda INSERT wynosiła 6,7x dla mnie szybsza niż metoda TRANSAKCJA. Próbowałem na zestawie zarówno 3000, jak i 30 000 wierszy.

Metoda TRANSACTION nadal musi uruchamiać każde zapytanie indywidualnie, co zajmuje dużo czasu, chociaż podczas wykonywania powoduje zapisanie wyników w pamięci lub coś w tym stylu. Metoda TRANSACTION jest także dość droga zarówno w dziennikach replikacji, jak i dzienników zapytań.

Co gorsza, metoda CASE była o 41,1x wolniejsza niż metoda INSERT z 30 000 rekordów (6,1x wolniejsza niż TRANSACTION). I 75 razy wolniej w MyISAM. Metody INSERT i CASE pobiły nawet przy ~ 1000 rekordów. Nawet przy 100 rekordach metoda CASE jest BARELY szybsza.

Ogólnie rzecz biorąc, uważam, że metoda INSERT jest zarówno najlepsza, jak i najłatwiejsza w użyciu. Zapytania są mniejsze i łatwiejsze do odczytania i podejmują tylko 1 zapytanie działania. Dotyczy to zarówno InnoDB, jak i MyISAM.

Materiały dodatkowe:

Rozwiązaniem problemu non-default-polowego INSERT jest tymczasowo wyłączyć odpowiednie tryby SQL: SET SESSION sql_mode=REPLACE(REPLACE(@@SESSION.sql_mode,"STRICT_TRANS_TABLES",""),"STRICT_ALL_TABLES",""). Pamiętaj, aby zapisać sql_modepierwszy, jeśli planujesz go cofnąć.

Co do innych komentarzy, które widziałem, że auto_increment idzie w górę za pomocą metody INSERT, wydaje się, że tak jest w InnoDB, ale nie w MyISAM.

Kod do uruchomienia testów jest następujący. Wysyła również pliki .SQL, aby usunąć narzut interpretera 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).';');
}
Dakusan
źródło
1
Wykonujecie tutaj pracę Pana;) Bardzo doceniam.
chili
Testując wydajność między GoLang i PHP, używając 40k wierszy na MariaDB, otrzymałem 2 sekundy na PHP i ponad 6 sekund na golang .... Cóż, zawsze mówiono mi, że GoLang będzie działał szybciej niż PHP !!! Więc zaczynam się zastanawiać, jak poprawić wydajność ... Używając INSERT ... W DUPLICATE KEY UPDATE ... Mam 0,74 sekundy na Golang i 0,86 sekundy na PHP !!!!
Diego Favero,
1
Celem mojego kodu jest ograniczenie wyników taktowania wyłącznie do instrukcji SQL, a nie kodu języka lub bibliotek. GoLang i PHP to 2 całkowicie odrębne języki przeznaczone do zupełnie różnych rzeczy. PHP jest przeznaczone do pojedynczego uruchamiania środowiska skryptowego w jednym wątku z przeważnie ograniczonym i pasywnym zbieraniem pamięci. GoLang jest przeznaczony do długotrwałych kompilowanych aplikacji z agresywnym odśmiecaniem pamięci i wielowątkowością jako jedną z podstawowych funkcji językowych. Nie mogą się bardziej różnić pod względem funkcjonalności języka i powodu. [Ciąg dalszy]
Dakusan,
Dlatego podczas uruchamiania testów należy ograniczyć pomiary prędkości wyłącznie do funkcji „Query”, która wywołuje instrukcję SQL. Porównywanie i optymalizacja innych części kodu źródłowego, które nie są ściśle wywołaniami zapytania, jest jak porównywanie jabłek i pomarańczy. Jeśli ograniczysz swoje wyniki do tego (mając wstępnie skompilowane ciągi i gotowe do użycia), wyniki powinny być bardzo podobne. Wszelkie różnice w tym punkcie są winą biblioteki SQL języka, a niekoniecznie samego języka. Moim zdaniem, rozwiązanie INSERT ON DUPLICATE było i zawsze będzie najlepszą opcją. [
Cd
Jeśli chodzi o twój komentarz na temat szybszego działania GoLanga, jest to niezwykle szerokie stwierdzenie, które nie bierze pod uwagę żadnego z wielu zastrzeżeń lub niuansów tych języków i ich konstrukcji. Java jest językiem interpretowanym, ale dowiedziałem się 15 lat temu, że w niektórych scenariuszach może w rzeczywistości niemal dorównać (a czasem nawet pokonać) C. A C to język skompilowany i najpopularniejszy z języków systemowych najniższego poziomu, oprócz asemblera. Naprawdę uwielbiam to, co robi GoLang i zdecydowanie ma moc i płynność, aby stać się jednym z najpopularniejszych systemów i zoptymalizowanym [cd]
Dakusan
9

Użyj tabeli tymczasowej

// 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`");
}
Laymain
źródło
8
UPDATE table1, table2 SET table1.col1='value', table2.col1='value' WHERE table1.col3='567' AND table2.col6='567'

To powinno na ciebie zadziałać.

W podręczniku MySQL znajduje się odniesienie do wielu tabel.

UnkwnTech
źródło
6

Dlaczego nikt nie wspomina o wielu instrukcjach w jednym zapytaniu ?

W php używasz multi_querymetody instancji mysqli.

Z podręcznika php

MySQL opcjonalnie pozwala na posiadanie wielu instrukcji w jednym ciągu instrukcji. Wysyłanie wielu instrukcji jednocześnie zmniejsza liczbę podróży między klientem a serwerem, ale wymaga specjalnej obsługi.

Oto wynik w porównaniu z innymi 3 metodami w aktualizacji 30 000 raw. Kod można znaleźć tutaj, który jest oparty na odpowiedzi z @Dakusan

Transakcja: 5.5194580554962
Wkładka: 0.20669293403625
Obudowa: 16.474853992462
Multi: 0,0412278175354

Jak widać, zapytanie z wieloma instrukcjami jest wydajniejsze niż najwyższa odpowiedź.

Jeśli pojawi się taki komunikat o błędzie:

PHP Warning:  Error while sending SET_OPTION packet

Może być konieczne zwiększenie max_allowed_packetpliku konfiguracyjnego mysql, który znajduje się na moim komputerze, /etc/mysql/my.cnfa następnie ponowne uruchomienie mysqld.

mononoke
źródło
Wszystkie poniższe porównania porównano z testem INSERT. Właśnie uruchomiono test w tych samych warunkach i bez transakcji, było 145x wolniej na 300 wierszy i 753x wolniej 3000 wierszy. Najpierw zacząłem od 30 000 wierszy, ale poszedłem zrobić sobie lunch i wróciłem, a ono wciąż trwało. Ma to sens, ponieważ uruchamianie poszczególnych zapytań i opróżnianie każdego z nich indywidualnie do bazy danych byłoby absurdalnie drogie. Zwłaszcza z replikacją. Włączanie transakcji ma jednak duże znaczenie. Przy 3000 wierszy zajęło to 1,5x więcej, a przy 30 000 wierszy 2,34x . [ciąg dalszy]
Dakusan
Ale miałeś rację, mówiąc, że jest szybki (z transakcjami). Zarówno w 3000, jak i 30 000 wierszy było ono szybsze niż wszystko oprócz metody INSERT. Nie ma absolutnie żadnego sposobu, aby uzyskać lepsze wyniki z uruchomienia 1 zapytania niż 30 000 zapytań, nawet jeśli są one połączone w specjalne wywołanie API MySQL. Działając tylko 300 wierszy, był DUŻO szybszy niż wszystkie inne metody (ku mojemu zdziwieniu), która podąża za tą samą krzywą graficzną co metoda CASE. Szybkość tę można wyjaśnić na 2 sposoby. Po pierwsze, metoda INSERT zasadniczo zawsze wstawia 2 wiersze ze względu na „ON DUPLICATE KEY [cd]
Dakusan
UPDATE ”powoduje zarówno„ INSERT ”, jak i„ UPDATE ”. Z drugiej strony jest mniej pracy w procesorze SQL do edytowania tylko 1 wiersza na raz ze względu na wyszukiwanie indeksów. Nie jestem pewien, jak uzyskałeś inne wyniki niż ja, ale Twój dodatkowy test wygląda solidnie. Właściwie nie jestem nawet pewien, w jaki sposób replikacja poradziłaby sobie z tym wywołaniem. To działałoby również tylko w przypadku wykonywania wywołań UPDATE. Wstawianie wywołań ZAWSZE będzie najszybsze dzięki pojedynczemu zapytaniu INSERT.
Dakusan
Robiłem 300 aktualizacji na raz na stole, aby skorygować błąd w pętli for, co zajęło 41 sekund. Umieszczenie tych samych zapytań UPDATE w jednym $mysqli->multi_query($sql)zajęło „0” sekund. Jednak kolejne zapytania nie powiodły się, przez co uczyniłem z tego osobny „program”.
Chris K
Dzięki. Był w stanie zaktualizować około 5 tysięcy wierszy (nie testowałem więcej) w ciągu minuty przy użyciu wielu zapytań. Jeśli ktoś szuka rozwiązania PDO: stackoverflow.com/questions/6346674/…
Scofield
3

Istnieje ustawienie, które można zmienić, nazywane „instrukcją wielokrotną”, które wyłącza „mechanizm bezpieczeństwa” MySQL zaimplementowany w celu zapobiegania (więcej niż jednemu) poleceniu wstrzyknięcia. Typowa dla „genialnej” implementacji MySQL, zapobiega także wydajnym zapytaniom użytkownika.

Tutaj ( http://dev.mysql.com/doc/refman/5.1/en/mysql-set-server-option.html ) znajduje się kilka informacji na temat implementacji ustawienia C.

Jeśli używasz PHP, możesz używać mysqli do wykonywania wielu instrukcji (myślę, że php jest już dostępny z mysqli)

$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();

Mam nadzieję, że to pomaga.

Strumyki
źródło
4
Jest to to samo, co wysyłanie zapytań osobno. Jedyna różnica polega na tym, że wysyłasz wszystko w jednym pakiecie sieciowym, ale UPDATE będą nadal przetwarzane jako osobne zapytania. Lepiej jest zawinąć je w jedną transakcję, wtedy zmiany zostaną natychmiast zatwierdzone w tabeli.
Marki555
3
Jak zawinąć je w jedną transakcję? Pokaż nam, proszę.
TomeeNS
@TomeeNS Użyj mysqli::begin_transaction(..)przed wysłaniem zapytania i mysql::commit(..)po nim. Lub użyj START TRANSACTIONjako pierwszej i COMMITostatniej instrukcji w samym zapytaniu.
Juha Palomäki
3

Możesz aliasować tę samą tabelę, aby uzyskać identyfikatory, które chcesz wstawić (jeśli wykonujesz aktualizację wiersz po wierszu:

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

Ponadto powinno wydawać się oczywiste, że możesz także aktualizować z innych tabel. W takim przypadku aktualizacja pełni również funkcję instrukcji „SELECT”, podając dane z określonej tabeli. W zapytaniu wyraźnie podajesz wartości aktualizacji, więc druga tabela pozostaje nienaruszona.

jaja
źródło
2

Możesz także być zainteresowany korzystaniem z połączeń w aktualizacjach, co jest również możliwe.

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.

Edycja: jeśli wartości, które aktualizujesz, nie pochodzą z innej bazy danych, musisz wydać wiele zapytań o aktualizację.

Shawn
źródło
1

A teraz prosty sposób

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
Stan Sokolov
źródło
-1

posługiwać się

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

Proszę zanotować:

  • id musi być podstawowym unikalnym kluczem
  • jeśli użyjesz kluczy obcych do odwołania się do tabeli, REPLACE usuwa następnie wstawia, więc może to spowodować błąd
Justin Levene
źródło
-3

Poniższe zaktualizuje wszystkie wiersze w jednej tabeli

Update Table Set
Column1 = 'New Value'

Następny zaktualizuje wszystkie wiersze, w których wartość kolumny 2 jest większa niż 5

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

Istnieje cały przykład Unkwntech dotyczący aktualizacji więcej niż jednej tabeli

UPDATE table1, table2 SET
table1.col1 = 'value',
table2.col1 = 'value'
WHERE
table1.col3 = '567'
AND table2.col6='567'
GateKiller
źródło
-3

Tak .. jest to możliwe przy użyciu instrukcji INSERT ON DUPLICATE KEY UPDATE sql .. składnia: INSERT INTO nazwa_tabeli (a, b, c) VALUES (1,2,3), (4,5,6) ON DUPLICATE KEY UPDATE a = WARTOŚCI (a), b = WARTOŚCI (b), c = WARTOŚCI (c)

sara191186
źródło
-5
UPDATE tableName SET col1='000' WHERE id='3' OR id='5'

To powinno osiągnąć to, czego szukasz. Po prostu dodaj więcej identyfikatorów. Przetestowałem to.

UnkwnTech
źródło
-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`) 

// Po prostu budujesz go w 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);

Możesz więc zaktualizować tabelę otworów za pomocą jednego zapytania

użytkownik2082581
źródło
Nie przegłosowałem, ale myślę, że sprzeciwiam się zrobieniu zestawu, gdy nie jest to potrzebne (a ty wciąż to robisz, gdy ustawiasz somethingsię something)
v010dya