No se puede eliminar o actualizar una fila principal: falla una restricción de clave foránea


Al hacer:

DELETE FROM `jobs` WHERE `job_id` =1 LIMIT 1 

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`);
Author: Eric Leschinski, 2009-12-15

13 answers

Tal como está, debe eliminar la fila de la tabla anunciantes antes de poder eliminar la fila de la tabla trabajos a la que hace referencia. Esto:

ALTER TABLE `advertisers`
  ADD CONSTRAINT `advertisers_ibfk_1` FOREIGN KEY (`advertiser_id`) 
      REFERENCES `jobs` (`advertiser_id`);

Is es en realidad lo opuesto a lo que debería ser. Tal como está, significa que usted tendría que tener un registro en la tabla de trabajos antes de los anunciantes. Así que 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 foránea, su instrucción delete funcionará.

 74
Author: OMG Ponies,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-09 13:49:39

La forma más sencilla sería desactivar la comprobación de claves foráneas; realice los cambios y vuelva a habilitar la comprobación de claves foráneas.

SET FOREIGN_KEY_CHECKS=0; -- to disable them
SET FOREIGN_KEY_CHECKS=1; -- to re-enable them
 190
Author: Alino Manzi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-07-24 08:11:01

Bajo su diseño actual (posiblemente defectuoso), debe eliminar la fila de la tabla de anunciantes antes de puede eliminar la fila de la tabla de trabajos a la que hace referencia.

Alternativamente, puede configurar su clave foránea de manera que una eliminación en la tabla padre haga que las filas en las tablas secundarias se eliminen automáticamente. Esto se denomina 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;

Dicho esto, como otros ya han señalado, su clave foránea se siente al igual que debería ir al revés, ya que la tabla de anunciantes realmente contiene la clave primaria 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.

 27
Author: Asaph,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-11-13 22:55:22

Si desea eliminar una tabla, debe ejecutar la siguiente consulta en un solo paso

SET FOREIGN_KEY_CHECKS = 0; DROP TABLE table_name;

 13
Author: Abin John,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-11-11 10:06:38

Creo que tu clave foránea está al revés. Try:

ALTER TABLE 'jobs'
ADD CONSTRAINT `advertisers_ibfk_1` FOREIGN KEY (`advertiser_id`) REFERENCES `advertisers` (`advertiser_id`)
 5
Author: Tom H,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-12-15 06:16:09

Si hay más de un trabajo con el mismo advertiser_id, entonces su clave foránea 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 en advertiser se eliminen automáticamente si se elimina 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 Restricciones de clave externa

 3
Author: Rashmi Pandit,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-12-15 06:25:35

Cuando se crea una base de datos o se crean tablas

Debe agregar esa línea en la parte superior script create database or table

SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=1;

Ahora desea 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!

 2
Author: Quy Le,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-05-08 07:25:06

Tuve este problema en 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 que no funcione, pero si cambia el orden, funciona.

Schema::dropIfExists('contact');
Schema::dropIfExists('groups');
 2
Author: Amin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-09-01 16:17:20

Debe eliminarlo por orden Hay dependencia en las tablas

 1
Author: Ran Adler,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-05-14 07:30:26

¿ Qué tal esta alternativa que he estado usando: permitir que la clave foránea sea NULL y luego elija ON DELETE SET NULL.

Personalmente prefiero usar tanto " ON UPDATE CASCADE" como " ON DELETE SET NULL" para evitar complicaciones innecesarias, pero en su configuración puede que desee un enfoque diferente. Además, los valores de clave foránea anulados pueden provocar complicaciones, ya que no sabrá qué sucedió exactamente allí. Así que este cambio debe estar en estrecha relación con cómo funciona el código de su aplicación.

Espero que esto ayude.

 1
Author: Marius Cucuruz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-09 10:54:41

Si necesita apoyar al cliente lo antes posible, y no tiene acceso a

FOREIGN_KEY_CHECKS

Para que la integridad de los datos pueda ser desactivada:

1) eliminar la clave externa

ALTER TABLE `advertisers` 
DROP FOREIGN KEY `advertisers_ibfk_1`;

2) active su operación de eliminación a través de sql o api

3) volver a añadir 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 rápida, por lo que es bajo su propio riesgo, porque el defecto principal de tal enfoque es que se necesita después para mantener la integridad de los datos manualmente.

 0
Author: Oleksii Kyslytsyn,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-07-26 09:50:57

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 ;
 0
Author: Patch92,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-01-06 20:01:00

Tal vez deberías intentar ELIMINAR CASCADE

 -1
Author: ,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-12-15 06:16:28