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?
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?
Odpowiedzi:
Weźmy przypadek dwóch tabel Books
i Orders
. W przypadku, gdy zwiększamy liczbę książek w określonej kolejności Order.ID = 1002
w Orders
tabeli, musimy również zmniejszyć tę całkowitą liczbę książek dostępnych w naszym magazynie o tę samą liczbę w Books
tabeli.
UPDATE Books, Orders
SET Orders.Quantity = Orders.Quantity + 2,
Books.InStock = Books.InStock - 2
WHERE
Books.BookID = Orders.BookID
AND Orders.OrderID = 1002;
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ój books
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łowymi author_id
s. Jako administrator danych nie chcesz przechodzić przez wszystkie te elementy, books
aby sprawdzić, co author_id
powinno być, więc zostaje podjęta decyzja, że osoby przechwytujące dane naprawią books
punkt po prawej stronie authors
. 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 ma INNER 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
.
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").
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 ().
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.
Powiedzmy, że mam Table1
z kluczem podstawowym _id
i kolumną logiczną doc_availability
; Table2
z kluczem obcym _id
i kolumną DateTime last_update
i chcę zmienić dostępność dokumentu z _id
14 Table1
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