Questo errore si presenta quando si tenta di aggiornare una tabella prelevando i dati dalla medesima. Per comprendere il problema immaginiamo di avere una tabella come la seguente:
id | indirizzo |
1 | http://indirizzosito.com/?opzione= |
2 | bianco |
3 | nero |
Adesso supponiamo di volerla modificare in modo tale che il campo indirizzo all’
id = 1 venga concatenato come prefisso su tutti gli altri campi
indirizzo con
id > 1. Quello che vogliamo ottenere è una tabella simile a questa:
id | indirizzo |
1 | http://indirizzosito.com/?opzione= |
2 | http://indirizzosito.com/?opzione=bianco |
3 | http://indirizzosito.com/?opzione=nero |
Prima di cominciare possiamo generare la tabella di prova con:
1 2 3 4 |
CREATE TABLE `elenco_importato` ( `id` int(255) NOT NULL, `indirizzo` varchar(1024) NOT NULL ) ENGINE=InnoDB DEFAULT CHARSET=latin1; |
Ed inseriamo dentro i dati con:
1 2 3 4 5 6 7 8 9 |
INSERT INTO `elenco_importato` (`id`, `indirizzo`) VALUES (1, 'http://indirizzosito.com/?opzione='), (2, 'bianco'), (3, 'nero'), (4, 'giallo'), (5, 'verde'), (6, 'oro'), (7, 'blu'), (8, 'pervinca'); |
A questo punto verrebbe spontaneo pensare che si possa utilizzare la seguente query (ATTENZIONE! Questa non funziona!):
1 2 3 4 5 6 7 8 |
UPDATE elenco_importato AS t1 SET t1.indirizzo = CONCAT( (SELECT t2.indirizzo FROM elenco_importato AS t2 WHERE t2.id = 1), t1.indirizzo ) WHERE t1.id > 1 |
Questa query produce però il seguente messaggio di errore:
#1093 – Table ‘t1’ is specified twice, both as a target for ‘UPDATE’ and as a separate source for data
L’errore dipende dal fatto che il database non ci consente di modificare una tabella dalla quale preleviamo contemporaneamente i dati. Possiamo aggirare il problema “ingannando” il database con la seguente modifica:
1 2 3 4 5 6 7 8 |
UPDATE elenco_importato AS t1 SET t1.indirizzo = CONCAT( (SELECT t2.indirizzo FROM (SELECT * FROM elenco_importato) AS t2 WHERE t2.id = 1), t1.indirizzo ) WHERE t1.id > 1 |
Faccio notare che a:
1 |
elenco_importato AS t2 |
Abbiamo sostituito:
1 |
(SELECT * FROM elenco_importato) AS t2 |
In questo modo la tabella viene per prima cosa prelevata e poi utilizzata per i dati dell’UPDATE.