2009-03-05 24 views
17

Tengo una tabla de MySQL autorreferencial con un parent_id recursiva:¿Cuál es la mejor manera de vaciar una tabla MySQL autorreferencial?

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 

Durante las pruebas, quiero vaciarlo pero TRUNCATE falla:

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

En este momento tengo que borrar manualmente todos los registros, comenzando en la parte inferior del árbol trabajando hacia arriba. Esto se vuelve oneroso incluso con árboles pequeños.

¿Hay una manera fácil de evitar esto? No puedo DROP la tabla y volver a crearla fácilmente a medida que otras tablas la referencian (ya he truncado esas por lo que no debería haber problemas de integridad de datos allí).

+0

Si "Borrar de la' 'POR ORDEN recursive' id' "harás que funcione. Sin embargo, si tiene filas de referencia automática, no tiene opciones elegantes: http://bugs.mysql.com/bug.php?id=7412. El que inhabilita foreign_keys temporalmente es el mejor. –

+1

Uno de los pocos casos que Oracle hace mejor, como en oráculo, puede defare a la verificación de restricciones hasta que la transacción se compromete. –

Respuesta

22

Por qué no:

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

?

+0

La pregunta "¿Cuál es la mejor manera de vaciar una tabla MySQL autorreferencial?" o una forma de ello aparece en tantos sitios de Internet e incluso se duplica varias veces al SO, y sin embargo, pocas de las preguntas tienen esta respuesta simple, elegante y correcta. +1 – Barzee

1

Bueno, podría agregar un ON DELETE CASCADE a la definición FOREIGN KEY ... al menos temporalmente. Eso le permitiría truncar la tabla eliminando primero las filas referenciadas.

También hay otros tipos ON DELETE; el valor predeterminado es ON DELETE NO ACTION.

-1

Seleccione repetidamente las filas que no aparecen como padres y elimínelas, hasta que la tabla esté vacía. (Suponiendo que no hay ciclos ...)

0

O simplemente elimine la restricción de la clave foránea (recursiva), trunque la tabla y luego vuelva a agregar el contraint.

16

Si lo que desea es vaciar todo el asunto para propósitos de prueba usar:

SET FOREIGN_KEY_CHECKS = 0; 

// Execute Query 

SET FOREIGN_KEY_CHECKS = 1; 

Esto evita totalmente cualquier revisión de las llaves extranjeras.

-2

eliminar de table_1 donde la fecha (table_1_TIME) < (T.t_Date seleccionar a partir de (select max (fecha (table_1_TIME)) como t_Date de table_1) como T)

+0

Formatee el código más claramente y haga referencia a los identificadores de la pregunta original. – gwaigh

Cuestiones relacionadas