Tengo un problema un poco extraño. Estoy tratando de agregar una clave externa a una tabla que hace referencia a otra, pero está fallando por alguna razón. Con mi conocimiento limitado de MySQL, lo único que podría ser sospechoso es que hay una clave externa en una tabla diferente que hace referencia a la que estoy tratando de hacer referencia.
He hecho una SHOW CREATE TABLE
consulta en ambas tablas, sourcecodes_tags
es la tabla con la clave externa, sourcecodes
es la tabla referenciada.
CREATE TABLE `sourcecodes` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`user_id` int(11) unsigned NOT NULL,
`language_id` int(11) unsigned NOT NULL,
`category_id` int(11) unsigned NOT NULL,
`title` varchar(40) CHARACTER SET utf8 NOT NULL,
`description` text CHARACTER SET utf8 NOT NULL,
`views` int(11) unsigned NOT NULL,
`downloads` int(11) unsigned NOT NULL,
`time_posted` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
KEY `user_id` (`user_id`),
KEY `language_id` (`language_id`),
KEY `category_id` (`category_id`),
CONSTRAINT `sourcecodes_ibfk_3` FOREIGN KEY (`language_id`) REFERENCES `languages` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT `sourcecodes_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT `sourcecodes_ibfk_2` FOREIGN KEY (`category_id`) REFERENCES `categories` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=latin1
CREATE TABLE `sourcecodes_tags` (
`sourcecode_id` int(11) unsigned NOT NULL,
`tag_id` int(11) unsigned NOT NULL,
KEY `sourcecode_id` (`sourcecode_id`),
KEY `tag_id` (`tag_id`),
CONSTRAINT `sourcecodes_tags_ibfk_1` FOREIGN KEY (`tag_id`) REFERENCES `tags` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=latin1
Este es el código que genera el error:
ALTER TABLE sourcecodes_tags ADD FOREIGN KEY (sourcecode_id) REFERENCES sourcecodes (id) ON DELETE CASCADE ON UPDATE CASCADE
Respuestas:
Es muy probable que su
sourcecodes_tags
tabla contengasourcecode_id
valores que ya no existen en susourcecodes
tabla. Tienes que deshacerte de esos primero.Aquí hay una consulta que puede encontrar esos ID:
fuente
UPDATE sourcecodes_tags SET sourcecode_id = NULL WHERE sourcecode_id NOT IN (SELECT id FROM sourcecodes)
debería ayudar a deshacerse de esas identificaciones. O sinull
no está permitidosourcecode_id
, elimine esas filas o agregue esos valores faltantes a lasourcecodes
tabla.SELECT Tchild.id FROM Tchild INNER JOIN Tmain ON Tmain.id = Tchild.fk_id WHERE Tmain.id IS NULL
no devuelve nada, ¡así que el problema está en otra parte!UPDATE `homestead`.`automations` SET `deleted_at`=NULL WHERE deleted_at IS NOT NULL;
, lo que no implicaba ninguna clave foránea, así que estaba confundido. Pero el hecho de que mi tabla de contactos no tenía algunos registros a los que se refería la tabla de automatizaciones hizo que arrojara este "Código de error: 1452. No se puede agregar o actualizar una fila secundaria: falla una restricción de clave externa".Tuve el mismo problema con mi base de datos MySQL pero finalmente, obtuve una solución que funcionó para mí.
Como en mi tabla todo estaba bien desde el punto de vista de mysql (ambas tablas deberían usar el motor InnoDB y el tipo de datos de cada columna debería ser del mismo tipo que participa en la restricción de clave externa).
Lo único que hice fue deshabilitar la verificación de clave externa y luego habilitarla después de realizar la operación de clave externa.
Pasos que tomé:
fuente
Use
NOT IN
para encontrar dónde las restricciones son limitantes :entonces, más específicamente:
EDIT:
IN
yNOT IN
operadores son conocidos por ser mucho más rápido que losJOIN
operadores, así como mucho más fáciles de construir, y repetir.fuente
Trunca las tablas y luego intenta agregar la restricción FK .
Sé que esta solución es un poco incómoda, pero funciona al 100%. Pero estoy de acuerdo en que esta no es una solución ideal para lidiar con el problema, pero espero que ayude.
fuente
Para mí, este problema fue un poco diferente y muy fácil de verificar y resolver.
Debe asegurarse de que AMBAS tablas sean InnoDB. Si una de las tablas, es decir, la tabla de referencia es MyISAM, la restricción fallará.
fuente
Esto también ocurre cuando se configura una clave foránea para parent.id en child.column si child.column ya tiene un valor de 0 y ningún valor parent.id es 0
Debería asegurarse de que cada child.column sea NULL o tenga un valor que exista en parent.id
Y ahora que leí la declaración que escribimos, eso es lo que está validando.
fuente
Tuve el mismo problema hoy. Probé cuatro cosas, algunas de ellas ya mencionadas aquí:
¿Hay algún valor en su columna secundaria que no exista en la columna primaria (además de NULL, si la columna secundaria es anulable)
¿Las columnas hijo y padre tienen el mismo tipo de datos?
¿Hay un índice en la columna principal a la que hace referencia? MySQL parece requerir esto por razones de rendimiento ( http://dev.mysql.com/doc/refman/5.5/en/create-table-foreign-keys.html )
Y este lo resolvió para mí: ¿Ambas tablas tienen una clasificación idéntica?
Tenía una mesa en UTF-8 y la otra en iso-algo. Eso no funcionó. Después de cambiar la clasificación iso-table a UTF-8, las restricciones podrían agregarse sin problemas. En mi caso, phpMyAdmin ni siquiera mostró la tabla secundaria en codificación iso en el menú desplegable para crear la restricción de clave externa.
fuente
Parece que hay un valor no válido para la línea de columna 0 que no es una clave externa válida, por lo que MySQL no puede establecer una restricción de clave externa para ella.
Puedes seguir estos pasos:
Suelte la columna para la que ha intentado establecer la restricción FK.
Agréguelo nuevamente y establezca su valor predeterminado como NULL.
Intente establecer una restricción de clave externa para él nuevamente.
fuente
Tenía el mismo problema, revisé las filas de mis tablas y descubrí que había cierta incompatibilidad con el valor de los campos que quería definir una clave externa. Corregí esos valores, intenté nuevamente y el problema se resolvió.
fuente
Termino borrando todos los datos de mi tabla y ejecuto alter nuevamente. Funciona. No es el brillante, pero ahorra mucho tiempo, especialmente su aplicación aún está en etapa de desarrollo sin ningún dato del cliente.
fuente
prueba esto
fuente
Tuve exactamente el mismo problema unas tres veces diferentes. En cada caso fue porque uno (o más) de mis registros no se ajustaba a la nueva clave externa. Es posible que desee actualizar sus registros existentes para seguir las restricciones de sintaxis de la clave externa antes de intentar agregar la clave en sí. El siguiente ejemplo generalmente debería aislar los registros de problemas:
repita
AND (candidate key) <> (next proposed foreign key value)
dentro de su consulta para cada valor en la clave externa.Si tiene una tonelada de registros, esto puede ser difícil, pero si su tabla es razonablemente pequeña, no debería demorar demasiado. No soy súper sorprendente en la sintaxis SQL, pero esto siempre me ha aislado el problema.
fuente
Vacíe los datos de ambas tablas y ejecute el comando. Funcionará.
fuente
Recibía este error cuando usaba Laravel y elocuente, intentar hacer un enlace de clave externa causaría un 1452. El problema era la falta de datos en la tabla vinculada.
Consulte aquí para ver un ejemplo: http://mstd.eu/index.php/2016/12/02/laravel-eloquent-integrity-constraint-violation-1452-foreign-key-constraint/
fuente
Estaba preparando estas soluciones y este ejemplo puede ayudar.
Mi base de datos tiene dos tablas (email y credit_card) con claves principales para sus ID. Otra tabla (cliente) se refiere a los ID de esta tabla como claves foráneas. Tengo una razón para tener el correo electrónico aparte de los datos del cliente.
Primero inserto los datos de la fila para las tablas a las que se hace referencia (correo electrónico, tarjeta de crédito), luego obtiene la ID para cada una, esas ID son necesarias en la tercera tabla (cliente).
Si no inserta primero las filas en las tablas referenciadas, MySQL no podrá hacer las correspondencias cuando inserte una nueva fila en la tercera tabla que haga referencia a las claves foráneas.
Si primero inserta las filas referenciadas para las tablas referenciadas, luego la fila que hace referencia a claves foráneas, no se produce ningún error.
Espero que esto ayude.
fuente
Asegúrese de que el valor esté en la otra tabla; de lo contrario, obtendrá este error en la columna correspondiente asignada.
Por lo tanto, si se asigna una columna a una ID de fila de otra tabla, asegúrese de que haya una fila en la tabla; de lo contrario, aparecerá este error.
fuente
puedes probar este ejemplo
Nota: si está utilizando phpmyadmin, simplemente desmarque Habilitar comprobaciones de clave externa
como ejemplo
Espero que esta solución solucione su problema :)
fuente
Solo necesita responder una pregunta:
¿Su tabla ya está almacenando datos? (Especialmente la tabla incluía clave foránea).
Si la respuesta es sí, entonces lo único que debe hacer es eliminar todos los registros, entonces puede agregar cualquier clave externa a su tabla.
La razón por la que no puede agregar una clave externa después de las entradas de datos se debe a la inconsistencia de la tabla, ¿cómo va a lidiar con una nueva clave externa en la tabla que llena los datos anteriores?
Si la respuesta es no, entonces siga otras instrucciones.
fuente
debería ayudar a deshacerse de esas identificaciones. O si
null
no está permitidosourcecode_id
, elimine esas filas o agregue esos valores faltantes a lasourcecodes
tabla.fuente
Tuve el mismo problema y encontré la solución, colocando en
NULL
lugar deNOT NULL
en la columna de clave externa. Aquí hay una consulta:MySQL ha ejecutado esta consulta!
fuente
En mi caso, creé una nueva tabla con la misma estructura, creé las relaciones con las otras tablas, luego extraje los datos en CSV de la tabla anterior que tiene el problema, luego importé el CSV a la nueva tabla y deshabilité la comprobación de clave externa y deshabilitó la interrupción de importación, todos mis datos se insertan en la nueva tabla que no tiene ningún problema con éxito, luego se elimina la tabla anterior.
Funcionó para mi.
fuente