Ho una funzione che aggiorna tre tabelle, ma per eseguire questa operazione utilizzo tre query. Vorrei utilizzare un approccio più conveniente per le buone pratiche.
Come posso aggiornare più tabelle in MySQL con una singola query?
Ho una funzione che aggiorna tre tabelle, ma per eseguire questa operazione utilizzo tre query. Vorrei utilizzare un approccio più conveniente per le buone pratiche.
Come posso aggiornare più tabelle in MySQL con una singola query?
Risposte:
Prendi il caso di due tavoli Books
e Orders
. Nel caso, aumentiamo il numero di libri in un ordine particolare con Order.ID = 1002
in Orders
tabella, quindi dobbiamo anche ridurre il numero totale di libri disponibili nel nostro magazzino dello stesso numero nella Books
tabella.
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';
Per vedere cosa aggiornerà, puoi convertirlo in un'istruzione select, ad esempio:
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';
Un esempio che utilizza le stesse tabelle dell'altra risposta:
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;
MODIFICARE:
Solo per divertimento, aggiungiamo qualcosa di un po 'più interessante.
Supponiamo che tu abbia una tabella books
e una tabella di authors
. Hai books
un author_id
. Ma quando il database è stato originariamente creato, non sono stati impostati vincoli di chiave esterna e successivamente un bug nel codice front-end ha causato l'aggiunta di alcuni libri con messaggi non validi author_id
. Come DBA non devi passare attraverso tutti questi books
per verificare quali author_id
dovrebbero essere, quindi viene presa la decisione che i catturatori di dati correggeranno il books
punto a destra authors
. Ma ci sono troppi libri per esaminarli e diciamo che sai che quelli che hanno unaauthor_id
corrispondente a un reale author
sono corretti. Sono solo quelli che hanno inesistenteauthor_id
che non sono validi. Esiste già un'interfaccia per gli utenti per aggiornare i dettagli del libro e gli sviluppatori non vogliono modificarlo solo per questo problema. Ma l'interfaccia esistente fa un INNER JOIN authors
, quindi tutti i libri con autori non validi sono esclusi.
Quello che puoi fare è questo: inserisci un record di autore falso come "Autore sconosciuto". Quindi aggiorna author_id
tutti i record errati per puntare all'autore sconosciuto. Quindi i catturatori di dati possono cercare tutti i libri con l'autore impostato su "Autore sconosciuto", cercare l'autore corretto e correggerli.
Come si aggiornano tutti i record errati per puntare all'autore sconosciuto? In questo modo (supponendo che l'autore sconosciuto author_id
sia 99999):
UPDATE books
LEFT OUTER JOIN authors ON books.author_id = authors.id
SET books.author_id = 99999
WHERE authors.id IS NULL;
Quanto sopra aggiornerà anche books
quello che ha un NULL
author_id
autore sconosciuto. Se non lo desideri, ovviamente puoi aggiungere AND books.author_id IS NOT NULL
.
Puoi anche farlo anche con una query usando un join in questo modo:
UPDATE table1,table2 SET table1.col=a,table2.col2=b
WHERE items.id=month.id;
E poi basta inviare questa query, ovviamente. Puoi leggere di più sui join qui: http://dev.mysql.com/doc/refman/5.0/en/join.html . Ci sono anche un paio di restrizioni per ordinare e limitare gli aggiornamenti di più tabelle che puoi leggere qui: http://dev.mysql.com/doc/refman/5.0/en/update.html (basta ctrl + f "join").
Di solito è a questo che servono le stored procedure: implementare diverse istruzioni SQL in una sequenza. Utilizzando i rollback, è possibile assicurarsi che vengano trattati come un'unità di lavoro, ovvero che vengano eseguiti tutti o nessuno di essi, per mantenere coerenti i dati.
Quando dici più query intendi più istruzioni SQL come in:
UPDATE table1 SET a=b WHERE c;
UPDATE table2 SET a=b WHERE d;
UPDATE table3 SET a=b WHERE e;
O più chiamate di funzione di query come in:
mySqlQuery(UPDATE table1 SET a=b WHERE c;)
mySqlQuery(UPDATE table2 SET a=b WHERE d;)
mySqlQuery(UPDATE table3 SET a=b WHERE e;)
Il primo può essere fatto usando una singola chiamata mySqlQuery se è quello che volevi ottenere, semplicemente chiama la funzione mySqlQuery nel modo seguente:
mySqlQuery(UPDATE table1 SET a=b WHERE c; UPDATE table2 SET a=b WHERE d; UPDATE table3 SET a=b WHERE e;)
Ciò eseguirà tutte e tre le query con una chiamata mySqlQuery ().