Mam funkcję, która aktualizuje trzy tabele, ale używam do tego trzech zapytań. Chciałbym zastosować wygodniejsze podejście do dobrych praktyk.
Jak mogę zaktualizować wiele tabel w MySQL za pomocą jednego zapytania?
mysql
sql
sql-update
Adamskiego
źródło
źródło
Odpowiedzi:
Weźmy przypadek dwóch tabel
Books
iOrders
. W przypadku, gdy zwiększamy liczbę książek w określonej kolejnościOrder.ID = 1002
wOrders
tabeli, musimy również zmniejszyć tę całkowitą liczbę książek dostępnych w naszym magazynie o tę samą liczbę wBooks
tabeli.UPDATE Books, Orders SET Orders.Quantity = Orders.Quantity + 2, Books.InStock = Books.InStock - 2 WHERE Books.BookID = Orders.BookID AND Orders.OrderID = 1002;
źródło
UPDATE t1 INNER JOIN t2 ON t2.t1_id = t1.id INNER JOIN t3 ON t2.t3_id = t3.id SET t1.a = 'something', t2.b = 42, t3.c = t2.c WHERE t1.a = 'blah';
Aby zobaczyć, co to ma zamiar zaktualizować, możesz przekonwertować to na instrukcję wyboru, np .:
SELECT t2.t1_id, t2.t3_id, t1.a, t2.b, t2.c AS t2_c, t3.c AS t3_c FROM t1 INNER JOIN t2 ON t2.t1_id = t1.id INNER JOIN t3 ON t2.t3_id = t3.id WHERE t1.a = 'blah';
Przykład wykorzystujący te same tabele co w drugiej odpowiedzi:
SELECT Books.BookID, Orders.OrderID, Orders.Quantity AS CurrentQuantity, Orders.Quantity + 2 AS NewQuantity, Books.InStock AS CurrentStock, Books.InStock - 2 AS NewStock FROM Books INNER JOIN Orders ON Books.BookID = Orders.BookID WHERE Orders.OrderID = 1002; UPDATE Books INNER JOIN Orders ON Books.BookID = Orders.BookID SET Orders.Quantity = Orders.Quantity + 2, Books.InStock = Books.InStock - 2 WHERE Orders.OrderID = 1002;
EDYTOWAĆ:
Dla zabawy dodajmy coś bardziej interesującego.
Powiedzmy, że masz tabelę
books
i tabelęauthors
. Twójbooks
miećauthor_id
. Ale kiedy baza danych została pierwotnie utworzona, nie ustawiono żadnych ograniczeń klucza obcego, a później błąd w kodzie interfejsu użytkownika spowodował, że niektóre książki zostały dodane z nieprawidłowymiauthor_id
s. Jako administrator danych nie chcesz przechodzić przez wszystkie te elementy,books
aby sprawdzić, coauthor_id
powinno być, więc zostaje podjęta decyzja, że osoby przechwytujące dane naprawiąbooks
punkt po prawej stronieauthors
. Ale jest zbyt wiele książek, aby przejść przez każdą z nich i powiedzmy, że wiesz, że te, które mająauthor_id
odpowiednik rzeczywistego,author
są poprawne. To tylko te, których nie maauthor_id
s, które są nieprawidłowe. Istnieje już interfejs umożliwiający użytkownikom aktualizację szczegółów książki, a programiści nie chcą tego zmieniać tylko z powodu tego problemu. Ale istniejący interfejs maINNER JOIN authors
, więc wszystkie książki z nieprawidłowymi autorami są wykluczone.Możesz to zrobić: wstaw fałszywy wpis autora, np. „Nieznany autor”. Następnie zaktualizuj
author_id
wszystkie złe rekordy, aby wskazywały na nieznanego autora. Następnie osoby przechwytujące dane mogą wyszukiwać wszystkie książki z autorem ustawionym na „Nieznany autor”, wyszukiwać właściwego autora i poprawiać go.Jak zaktualizować wszystkie złe rekordy, aby wskazywały na nieznanego autora? W ten sposób (zakładając, że autor nieznany
author_id
to 99999):UPDATE books LEFT OUTER JOIN authors ON books.author_id = authors.id SET books.author_id = 99999 WHERE authors.id IS NULL;
Powyższe zaktualizuje również,
books
które mająNULL
author_id
nieznanego autora. Jeśli tego nie chcesz, możesz oczywiście dodaćAND books.author_id IS NOT NULL
.źródło
Możesz to również zrobić za pomocą jednego zapytania, używając takiego sprzężenia:
UPDATE table1,table2 SET table1.col=a,table2.col2=b WHERE items.id=month.id;
A potem oczywiście wyślij to jedno zapytanie. Możesz przeczytać więcej o połączeniach tutaj: http://dev.mysql.com/doc/refman/5.0/en/join.html . Istnieje również kilka ograniczeń dotyczących zamawiania i ograniczania wielu aktualizacji tabel, o których możesz przeczytać tutaj: http://dev.mysql.com/doc/refman/5.0/en/update.html (po prostu ctrl + f "join").
źródło
Kiedy mówisz wiele zapytań, masz na myśli wiele instrukcji SQL, jak w:
UPDATE table1 SET a=b WHERE c; UPDATE table2 SET a=b WHERE d; UPDATE table3 SET a=b WHERE e;
Lub wiele wywołań funkcji zapytań, jak w:
mySqlQuery(UPDATE table1 SET a=b WHERE c;) mySqlQuery(UPDATE table2 SET a=b WHERE d;) mySqlQuery(UPDATE table3 SET a=b WHERE e;)
To pierwsze można zrobić za pomocą pojedynczego wywołania mySqlQuery, jeśli to właśnie chciałeś osiągnąć, po prostu wywołaj funkcję mySqlQuery w następujący sposób:
mySqlQuery(UPDATE table1 SET a=b WHERE c; UPDATE table2 SET a=b WHERE d; UPDATE table3 SET a=b WHERE e;)
Spowoduje to wykonanie wszystkich trzech zapytań za pomocą jednego wywołania mySqlQuery ().
źródło
Zwykle do tego służą procedury składowane: do zaimplementowania kilku instrukcji SQL w sekwencji. Korzystając z wycofywania zmian, możesz zapewnić, że są one traktowane jako jedna jednostka pracy, tj. Albo wszystkie są wykonywane, albo żadna z nich nie jest, aby zachować spójność danych.
źródło
Powiedzmy, że mam
Table1
z kluczem podstawowym_id
i kolumną logicznądoc_availability
;Table2
z kluczem obcym_id
i kolumną DateTimelast_update
i chcę zmienić dostępność dokumentu z_id
14Table1
na 0, tj. niedostępny i zaktualizowaćTable2
datownikiem, kiedy dokument był ostatnio aktualizowany. Następujące zapytanie wykonałoby zadanie:UPDATE Table1, Table2 SET doc_availability = 0, last_update = NOW() WHERE Table1._id = Table2._id AND Table1._id = 14
źródło