Troppe righe in modifica

GT mi ha proposto un problema semplice, ma che può dare dei mal di testa a chi non trova una spiegazione in fretta.

GT ha questa tabella


mysql> select * from luoghi;
+----------+----------+-----------+
| id_luogo | luogo | provincia |
+----------+----------+-----------+
| 41 | Ragusa | RG |
| 42 | Vasto | CH |
| 43 | Macerata | MC |
| 44 | Asola | MN |
| 45 | Palermo | PA |
| 49 | Prato | PO |
| 51 | Trento | TN |
| 37 | Firenze | FI |
| 38 | Piombino | LI |
| 50 | Borsano | VA |
+----------+----------+-----------+
10 rows in set (0.00 sec)

Il caso scaturisce dall’esecuzione dell’istruzione


REPLACE INTO luoghi SELECT * from vecchi_luoghi;

La tabella luoghi è una normalissima tabella con una chiave primaria e alcuni campi. La tabella contiene già dei record e GT ha inserito dei record prendendoli da vecchi dati. Alcuni di quelli già esistevano e per questo ha usato REPLACE invece di INSERT.

Il risultato dell’operazione è corretto. GT si ritrova nella tabella tutti i record che ci dovrebbero essere ed il loro valore è quello voluto.


mysql> select * from luoghi;
+----------+----------+-----------+
| id_luogo | luogo | provincia |
+----------+----------+-----------+
| 41 | Ragusa | RG |
| 42 | Vasto | CH |
| 43 | Macerata | MC |
| 44 | Asola | MN |
| 45 | Palermo | PA |
| 49 | Prato | PO |
| 51 | Trento | TN |
| 30 | Bologna | BO |
| 37 | Firenze | FI |
| 38 | Piombino | LI |
| 2 | Milano | MI |
| 1 | Parma | PR |
| 50 | Borsano | VA |
+----------+----------+-----------+
13 rows in set (0.00 sec)

Però, la faccenda nasce dal fatto che GT ha inserito 3 righe, e MySQL gli ha segnalato "9 rows affected"

GT è preoccupato per questa incongruenza e teme che si tratti di un bug, ma la spiegazione è semplice e rassicurante al tempo stesso. REPLACE è in realtà una scorciatoia che comprende due comandi: prima un DELETE, usando la chiave primaria, e poi un INSERT.

Tre delle righe inserite nella tabella esistevano già. Quindi REPLACE le ha cancellate ( = operazione su 3 righe ) e poi le ha inserite (altre 3 operazioni). Infine c’erano tre righe nuove, per le quali il comando DELETE ha dato risultato negativo (= nessuna riga interessata all’operazione) e infine l’inserimento ha prodotto 3 righe.

Il totale è 9 (3 cancellate + 6 inserite). Il dubbio è risolto e tutti possono andare a dormire tranquilli.