ERROR 1093 (HY000): You can't specify target table for update in FROM clause – MySQL 1093

1093

L'errore MySQL 1093 compare quando una query UPDATE o DELETE modifica una tabella e, nello stesso statement, la legge direttamente in una sottoquery. Il server evita così una forma ambigua di lettura e modifica simultanea. La riscrittura più chiara usa una tabella derivata, una Common Table Expression nelle versioni compatibili o un JOIN multi-tabella, verificando prima il piano e il risultato della SELECT.

Cosa significa questo errore?

L'errore MySQL 1093 compare quando una query UPDATE o DELETE modifica una tabella e, nello stesso statement, la legge direttamente in una sottoquery. Il server evita così una forma ambigua di lettura e modifica simultanea. La riscrittura più chiara usa una tabella derivata, una Common Table Expression nelle versioni compatibili o un JOIN multi-tabella, verificando prima il piano e il risultato della SELECT.

Messaggio originale

ERROR 1093 (HY000): You can't specify target table for update in FROM clause

Contesto e parole chiave

Alias

  • ER_UPDATE_TABLE_USED
  • SQLSTATE HY000
  • Target table used in subquery

Messaggi alternativi

  • Impossibile aggiornare e leggere direttamente la stessa tabella
  • La tabella aggiornata è usata nella sottoquery

Prodotti

  • MySQL / MariaDB Server

Piattaforme

  • Linux
  • macOS
  • Windows Server

Parole chiave

  • mysql errore 1093
  • mysql update subquery
  • target table used

Cause possibili

La sottoquery legge direttamente la tabella aggiornata

La stessa tabella compare sia nella clausola UPDATE/DELETE sia nella sottoquery che calcola il valore o l'elenco di righe.

molto comune

Mancanza di tabella derivata o CTE

La query non separa il risultato della lettura dal target della modifica tramite un livello intermedio.

comune

Diagnosi

Tutte le occorrenze della tabella nello statement

Isolare la SELECT della sottoquery ed eseguire prima solo la parte di lettura.

Come leggere il risultato. La SELECT chiarisce quali righe devono alimentare la modifica senza applicarla.

mysql
EXPLAIN SELECT id FROM items WHERE ...

Versione MySQL e supporto CTE

Verificare la versione prima di scegliere la sintassi di riscrittura.

Come leggere il risultato. La versione determina quali forme di CTE e derived table sono disponibili.

mysql
SELECT VERSION();

Risoluzione

Riscrittura con tabella derivata

Difficoltà: mediaRischio: medio

Separare la lettura dalla tabella aggiornata usando una derived table con alias.

  1. Eseguire la SELECT della sottoquery in sola lettura.
  2. Avvolgerla in una tabella derivata con alias.
  3. Collegare l'alias al target tramite JOIN o filtro.
  4. Verificare il numero di righe prima del commit.

Eseguire prima una SELECT equivalente e un backup se l'UPDATE è distruttivo.

Uso di CTE o tabella temporanea

Difficoltà: avanzataRischio: medio

Materializzare il risultato della lettura prima di modificare la tabella target quando la versione lo consente.

  1. Creare la CTE o la tabella temporanea con le chiavi interessate.
  2. Controllare il contenuto materializzato.
  3. Eseguire UPDATE o DELETE usando la chiave materializzata.
  4. Verificare il risultato e chiudere la transazione.

Una modifica massiva deve essere eseguita in transazione e con criteri verificati.

Domande frequenti

Perché una SELECT simile funziona ma l'UPDATE restituisce 1093?

La SELECT non modifica la tabella; l'errore nasce dalla combinazione di lettura diretta e modifica della stessa tabella nello stesso statement.

Approfondimenti

Schede correlate