2009-03-05 5 views
17

Ich habe eine selbstbezüglicher MySQL-Tabelle mit einer rekursiven parent_id:Was ist der beste Weg, um eine selbstreferentielle MySQL-Tabelle zu leeren?

CREATE TABLE `recursive` (
    `id` int(11) NOT NULL auto_increment, 
    `parent_id` int(11) default NULL, 
    `name` varchar(100) NOT NULL, 
    PRIMARY KEY (`id`), 
    KEY `data_categorysource_parent_id` (`parent_id`), 
    CONSTRAINT `parent_id_refs_id_627b4293` 
    FOREIGN KEY (`parent_id`) REFERENCES `data_categorysource` (`id`) 
) ENGINE=InnoDB DEFAULT CHARSET=utf8 

Während des Tests will ich es leer, aber TRUNCATE versagt:

TRUNCATE `recursive` 
/* SQL Error: Cannot delete or update a parent row: a foreign key 
constraint fails... 

ich zur Zeit manuell alle Datensätze löschen müssen, beginnend am Boden des Baumes, der aufwärts arbeitet. Dies wird auch mit kleinen Bäumen beschwerlich.

Gibt es einen einfachen Weg dahin? Ich kann nicht DROP die Tabelle und neu erstellen es leicht als andere Tabellen verweisen es (Ich habe bereits abgeschnitten, so dass es keine Datenintegritätsprobleme dort sein sollte).

+0

Wenn Sie „DELETE FROM' recursive' ORDER BY ' ID "Du wirst es Arbeit bekommen. Wenn Sie jedoch selbstverweisende Zeilen haben, sind Sie ziemlich ohne elegante Entscheidungen: http://bugs.mysql.com/bug.php?id=7412. Derjenige, der foreign_keys vorübergehend deaktiviert, ist der beste. –

+1

Einer der wenigen Fälle, in denen Orakel besser ist, wie in Orakel, können Sie sich auf die Überprüfung auf Einschränkungen beschränken, bis die Transaktion festgeschrieben wird. –

Antwort

22

Warum nicht:

UPDATE 'recursive' SET 'parent_id' = NULL WHERE 'parent_id' IS NOT NULL; 
DELETE FROM 'recursive'; 

?

+0

Die Frage "Was ist der beste Weg, um eine selbstreferentielle MySQL-Tabelle zu leeren?" oder eine Form davon erscheint auf so vielen Internetseiten und wird sogar mehrfach bei SO vervielfältigt, und dennoch haben so wenige der Fragen diese einfache, elegante und korrekte Antwort. +1 – Barzee

1

Nun, Sie könnten eine ON DELETE CASCADE zu der FOREIGN KEY Definition hinzufügen ... zumindest vorübergehend. Dadurch können Sie die Tabelle abschneiden, indem Sie zuerst die referenzierten Zeilen entfernen.

Es gibt andere ON DELETE Typen auch; Der Standardwert ist ON DELETE NO ACTION.

-1

Wiederholt die Zeilen auswählen, die nicht als Eltern angezeigt werden, und sie löschen, bis die Tabelle leer ist. (Angenommen, es gibt keine Zyklen ...)

0

Oder entfernen Sie einfach die (rekursive) Fremdschlüsseleinschränkung, dann schneiden Sie die Tabelle ab, und fügen Sie dann die Contraint wieder hinzu.

16

Wenn Sie wollen einfach nur für das Ganze leeren Testzwecken verwenden:

SET FOREIGN_KEY_CHECKS = 0; 

// Execute Query 

SET FOREIGN_KEY_CHECKS = 1; 

Dies umgeht völlig alle Fremdschlüsselprüfungen.

-2

von table_1 streichen Datum (table_1_TIME) < (wählen T.t_Date aus (wählen Sie max (Datum (table_1_TIME)) als t_Date von table_1) als T)

+0

Bitte formatieren Sie den Code klarer und verweisen Sie auf die Identifikatoren der ursprünglichen Frage. – gwaigh

Verwandte Themen