sql - restriccion - phpmyadmin error 1451
No se puede eliminar o actualizar una fila primaria: falla una restricción de clave externa (13)
¿Qué tal esta alternativa que he estado usando: permitir que la clave foránea sea NULL y luego elegir ON DELETE SET NULL ?
Personalmente, prefiero usar " ON UPDATE CASCADE " y " ON DELETE SET NULL " para evitar complicaciones innecesarias, pero en su configuración es posible que desee un enfoque diferente. Además, valores de clave externa NULL pueden generar complicaciones, ya que no sabrá qué sucedió exactamente allí. Por lo tanto, este cambio debe estar en estrecha relación con el funcionamiento del código de la aplicación.
Espero que esto ayude.
Al hacer:
DELETE FROM `jobs` WHERE `job_id` =1 LIMIT 1
Se errores:
#1451 - Cannot delete or update a parent row: a foreign key constraint fails
(paymesomething.advertisers, CONSTRAINT advertisers_ibfk_1 FOREIGN KEY
(advertiser_id) REFERENCES jobs (advertiser_id))
Aquí están mis tablas:
CREATE TABLE IF NOT EXISTS `advertisers` (
`advertiser_id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(255) NOT NULL,
`password` char(32) NOT NULL,
`email` varchar(128) NOT NULL,
`address` varchar(255) NOT NULL,
`phone` varchar(255) NOT NULL,
`fax` varchar(255) NOT NULL,
`session_token` char(30) NOT NULL,
PRIMARY KEY (`advertiser_id`),
UNIQUE KEY `email` (`email`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=2 ;
INSERT INTO `advertisers` (`advertiser_id`, `name`, `password`, `email`, `address`, `phone`, `fax`, `session_token`) VALUES
(1, ''TEST COMPANY'', '''', '''', '''', '''', '''', '''');
CREATE TABLE IF NOT EXISTS `jobs` (
`job_id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`advertiser_id` int(11) unsigned NOT NULL,
`name` varchar(255) NOT NULL,
`shortdesc` varchar(255) NOT NULL,
`longdesc` text NOT NULL,
`address` varchar(255) NOT NULL,
`time_added` int(11) NOT NULL,
`active` tinyint(1) NOT NULL,
`moderated` tinyint(1) NOT NULL,
PRIMARY KEY (`job_id`),
KEY `advertiser_id` (`advertiser_id`,`active`,`moderated`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=2 ;
INSERT INTO `jobs` (`job_id`, `advertiser_id`, `name`, `shortdesc`, `longdesc`, `address`, `active`, `moderated`) VALUES
(1, 1, ''TEST'', ''TESTTEST'', ''TESTTESTES'', '''', 0, 0);
ALTER TABLE `advertisers`
ADD CONSTRAINT `advertisers_ibfk_1` FOREIGN KEY (`advertiser_id`) REFERENCES `jobs` (`advertiser_id`);
Creo que su clave externa está al revés. Tratar:
ALTER TABLE ''jobs''
ADD CONSTRAINT `advertisers_ibfk_1` FOREIGN KEY (`advertiser_id`) REFERENCES `advertisers` (`advertiser_id`)
Cuando crea una base de datos o crea tablas
Debe agregar esa línea en la base de datos o tabla de creación de scripts superior
SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=1;
Ahora quieres eliminar registros de la tabla? entonces escribes como
SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=1;
DELETE FROM `jobs` WHERE `job_id` =1 LIMIT 1
¡Buena suerte!
Debes eliminarlo por orden Hay dependencia en las tablas
En su diseño actual (posiblemente defectuoso), debe eliminar la fila de la tabla de anunciantes antes de poder eliminar la fila en la tabla de trabajos a la que hace referencia.
De forma alternativa, puede configurar su clave externa de modo que una eliminación en la tabla primaria haga que las filas en las tablas secundarias se eliminen automáticamente. Esto se llama eliminación en cascada. Se ve algo como esto:
ALTER TABLE `advertisers`
ADD CONSTRAINT `advertisers_ibfk_1`
FOREIGN KEY (`advertiser_id`) REFERENCES `jobs` (`advertiser_id`)
ON DELETE CASCADE;
Una vez dicho esto, como ya han señalado otros, su clave externa parece que debe ir al revés, ya que la tabla de anunciantes contiene realmente la clave principal y la tabla de trabajos contiene la clave externa. Lo reescribiría así:
ALTER TABLE `jobs`
ADD FOREIGN KEY (`advertiser_id`) REFERENCES `advertisers` (`advertiser_id`);
Y la eliminación en cascada no será necesaria.
La forma más simple sería desactivar la verificación de la clave externa; hacer los cambios y luego volver a habilitar la verificación de la clave externa.
SET FOREIGN_KEY_CHECKS=0; -- to disable them
SET FOREIGN_KEY_CHECKS=1; -- to re-enable them
Puede crear un desencadenador para eliminar las filas a las que se hace referencia antes de eliminar el trabajo.
DELIMITER $$
CREATE TRIGGER before_jobs_delete
BEFORE DELETE ON jobs
FOR EACH ROW
BEGIN
delete from advertisers where advertiser_id=OLD.advertiser_id;
END$$
DELIMITER ;
Si desea soltar una tabla, debe ejecutar la siguiente consulta en un solo paso
SET FOREIGN_KEY_CHECKS = 0; DROP TABLE table_name;
Si hay más de un trabajo con el mismo public_id, su clave externa debería ser:
ALTER TABLE `jobs`
ADD CONSTRAINT `advertisers_ibfk_1`
FOREIGN KEY (`advertiser_id`)
REFERENCES `advertisers` (`advertiser_id`);
De lo contrario (si es al revés en su caso), si desea que las filas del anunciante se eliminen automáticamente si se borra la fila en el trabajo, agregue la opción ''ON DELETE CASCADE'' a su clave externa
ALTER TABLE `advertisers`
ADD CONSTRAINT `advertisers_ibfk_1`
FOREIGN KEY (`advertiser_id`)
REFERENCES `jobs` (`advertiser_id`);
ON DELETE CASCASE
Echa un vistazo a las restricciones de clave externa
Tal como está, debe eliminar la fila de la tabla de anunciantes antes de poder eliminar la fila en la tabla de trabajos a la que hace referencia. Esta:
ALTER TABLE `advertisers`
ADD CONSTRAINT `advertisers_ibfk_1` FOREIGN KEY (`advertiser_id`)
REFERENCES `jobs` (`advertiser_id`);
... es realmente lo contrario de lo que debería ser. Tal como está, significa que debe tener un registro en la tabla de trabajos antes que los anunciantes. Entonces necesitas usar:
ALTER TABLE `jobs`
ADD CONSTRAINT `advertisers_ibfk_1` FOREIGN KEY (`advertiser_id`)
REFERENCES `advertisers` (`advertiser_id`);
Una vez que corrija la relación de clave externa, su declaración de eliminación funcionará.
Tal vez deberías probar ON DELETE CASCADE
Tuve este problema en la migración laravel también
el orden de las tablas desplegables en el método down () sí importa
Schema::dropIfExists(''groups'');
Schema::dropIfExists(''contact'');
puede no funcionar, pero si cambias el orden, funciona.
Schema::dropIfExists(''contact'');
Schema::dropIfExists(''groups'');
si necesita apoyar al cliente lo antes posible, y no tiene acceso a
FOREIGN_KEY_CHECKS
para que la integridad de los datos se pueda deshabilitar:
1) eliminar la clave externa
ALTER TABLE `advertisers`
DROP FOREIGN KEY `advertisers_ibfk_1`;
2) active su operación de eliminación thruogh sql o api
3) agregue la clave foránea al esquema
ALTER TABLE `advertisers`
ADD CONSTRAINT `advertisers_ibfk_1` FOREIGN KEY (`advertiser_id`) REFERENCES `jobs` (`advertiser_id`);
sin embargo, es una solución caliente, por lo que es bajo su propio riesgo, ya que la falla principal de dicho enfoque es que luego se necesita para mantener la integridad de los datos manualmente.