7

Sto introducendo l'integrità del database utilizzando i vincoli innodb nella prossima versione della mia applicazione. Tutto va bene, ma alcune delle mie tabelle hanno record con riferimenti cancellati (record morti) e grazie a loro non posso aggiungere vincoli alla tabella.Gestione dell'integrità del database

sto provando:

ALTER TABLE `article` ADD FOREIGN KEY (`author_id`) REFERENCES `authors` (`id`) ON DELETE CASCADE; 

E ottengo:

#1452 - Cannot add or update a child row: a foreign key constraint fails (`books`.<result 2 when explaining filename '#sql-442_dc'>, CONSTRAINT `#sql-442_dc_ibfk_1` FOREIGN KEY (`author_id`) REFERENCES `authors` (`id`) ON DELETE CASCADE) 

esecuzione di questa query, ho scoperto che più di 500 record hanno nessun riferimento (autori sono stati cancellati, ma i loro articoli sono rimaste) :

SELECT `articles`.`id` 
FROM `articles` LEFT JOIN `authors` ON `articles`.`author_id` = `authors`.`id` 
WHERE ISNULL(`authors`.`id`); 

Quindi, prima di poter aggiungere un vincolo, devo occuparmene. Come si eliminano tutti i record che ottengo utilizzando la query sopra?

ho provato:

DELETE FROM `articles` WHERE `id` IN (
    SELECT `articles`.`id` 
    FROM `articles` LEFT JOIN `authors` ON `articles`.`author_id` = `authors`.`id` 
    WHERE ISNULL(`authors`.`id`); 
) 

Ma mysql risponde:

You can't specify target table 'articles' for update in FROM clause 

Qualsiasi aiuto su questo sarà molto apprezzato.

+0

Vedere qui: http://stackoverflow.com/questions/4770035/handling-database-integrity (duplicato) – Benj

+0

@Benj perché il tuo link punta a questo ** esatto ** SO post? –

+0

@BuhakeSindi Bene ... sembra che abbia fallito nel mio copia-incolla ... Grazie per averlo indicato. Mi dispiace non posso (anni dopo) recuperare il link originale. – Benj

risposta

14

Io non sono troppo familiarità con molte stranezze di MySQL, ma questo dovrebbe funzionare anche, e forse MySQL non soffocare su di esso:

delete from articles 
where not exists (
      select id from authors 
      where authors.id = articles.author_id 
     ) 

Um, ovviamente abbiamo sempre una copia di backup della tabella prima di tentare le eliminazioni basate su set :)

+0

+1, Non c'è bisogno di pubblicare il mio duplicato esatto :) – Ronnis

+0

+1 o il mio entrambi. –

+0

Grazie, ha funzionato per me! Ho già trovato una soluzione orribile usando un tavolo temporaneo, ma questo si rompe :) Lascerò una domanda aperta per un po 'di tempo in modo da poter ottenere più upvotes :) –

Problemi correlati