做的时候:
DELETE FROM `jobs` WHERE `job_id` =1 LIMIT 1
错误:
#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))
以下是我的表格:
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`);
答案 0 :(得分:218)
简单的方法是禁用外键检查;进行更改,然后重新启用外键检查。
SET FOREIGN_KEY_CHECKS=0; -- to disable them
SET FOREIGN_KEY_CHECKS=1; -- to re-enable them
答案 1 :(得分:84)
按原样,您必须先删除广告商表中的行,然后才能删除它引用的作业表中的行。这样:
ALTER TABLE `advertisers`
ADD CONSTRAINT `advertisers_ibfk_1` FOREIGN KEY (`advertiser_id`)
REFERENCES `jobs` (`advertiser_id`);
......实际上与应该是的相反。实际上,这意味着您必须在广告商之前在作业表中创建记录。所以你需要使用:
ALTER TABLE `jobs`
ADD CONSTRAINT `advertisers_ibfk_1` FOREIGN KEY (`advertiser_id`)
REFERENCES `advertisers` (`advertiser_id`);
更正外键关系后,您的删除语句将起作用。
答案 2 :(得分:29)
在您当前(可能有缺陷的)设计下,您必须删除广告商表之前的行,您可以删除它引用的作业表中的行。
或者,您可以设置外键,以便父表中的删除会导致子表中的行自动删除。这称为级联删除。它看起来像这样:
ALTER TABLE `advertisers`
ADD CONSTRAINT `advertisers_ibfk_1`
FOREIGN KEY (`advertiser_id`) REFERENCES `jobs` (`advertiser_id`)
ON DELETE CASCADE;
话虽如此,正如其他人已经指出的那样,你的外键感觉它应该反过来,因为广告商表真的包含主键而jobs表包含外键。我会像这样重写它:
ALTER TABLE `jobs`
ADD FOREIGN KEY (`advertiser_id`) REFERENCES `advertisers` (`advertiser_id`);
并不需要级联删除。
答案 3 :(得分:15)
如果要删除表,则应该一步执行以下查询
SET FOREIGN_KEY_CHECKS = 0; DROP TABLE table_name;
答案 4 :(得分:6)
我认为你的外键是倒退的。尝试:
ALTER TABLE 'jobs'
ADD CONSTRAINT `advertisers_ibfk_1` FOREIGN KEY (`advertiser_id`) REFERENCES `advertisers` (`advertiser_id`)
答案 5 :(得分:3)
禁用外键检查并进行更改,然后重新启用外键检查。
SET FOREIGN_KEY_CHECKS=0; -- to disable them
DELETE FROM `jobs` WHERE `job_id` = 1 LIMIT 1
SET FOREIGN_KEY_CHECKS=1; -- to re-enable them
答案 6 :(得分:3)
如果有多个作业具有相同的advertiser_id,那么您的外键应为:
ALTER TABLE `jobs`
ADD CONSTRAINT `advertisers_ibfk_1`
FOREIGN KEY (`advertiser_id`)
REFERENCES `advertisers` (`advertiser_id`);
否则(如果在您的情况下反之亦然),如果您希望在删除作业中的行时自动删除广告客户中的行,请在外键中添加“ON DELETE CASCADE”选项
ALTER TABLE `advertisers`
ADD CONSTRAINT `advertisers_ibfk_1`
FOREIGN KEY (`advertiser_id`)
REFERENCES `jobs` (`advertiser_id`);
ON DELETE CASCASE
答案 7 :(得分:2)
创建数据库或创建表时
您应该在顶部脚本create database或table
中添加该行SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=1;
现在要删除表中的记录?然后你写为
SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=1;
DELETE FROM `jobs` WHERE `job_id` =1 LIMIT 1
祝你好运!
答案 8 :(得分:2)
您需要按顺序删除它 表中存在依赖性
答案 9 :(得分:2)
我在 laravel migration 中也有这个问题 down()方法中drop table的顺序很重要
Schema::dropIfExists('groups');
Schema::dropIfExists('contact');
可能无效,但如果您更改订单,则可以正常工作。
Schema::dropIfExists('contact');
Schema::dropIfExists('groups');
答案 10 :(得分:2)
我尝试了@Alino Manzi提到的解决方案,但是在使用wpdb的WordPress相关表上,它对我不起作用。
然后我按如下所示修改了代码,
SET FOREIGN_KEY_CHECKS=OFF; //disabling foreign key
//run the queries which are giving foreign key errors
SET FOREIGN_KEY_CHECKS=ON; // enabling foreign key
答案 11 :(得分:1)
如果您需要尽快支持客户,并且无法访问
FOREIGN_KEY_CHECKS
以便可以禁用数据完整性:
1)删除外键
ALTER TABLE `advertisers`
DROP FOREIGN KEY `advertisers_ibfk_1`;
2)激活你的删除操作thruogh sql或api
3)将外键添加回架构
ALTER TABLE `advertisers`
ADD CONSTRAINT `advertisers_ibfk_1` FOREIGN KEY (`advertiser_id`) REFERENCES `jobs` (`advertiser_id`);
然而,这是一个热门修复,因此风险自负,因为这种方法的主要缺陷是之后需要手动保持数据完整性。
答案 12 :(得分:1)
我一直在使用的替代方法如何:允许外键 NULL ,然后选择 ON DELETE SET NULL
我个人更喜欢同时使用" ON UPDATE CASCADE "以及" ON DELETE SET NULL "为避免不必要的复杂情况,但在您的设置上,您可能需要采用不同的方法。此外,NULL和外键值可能会导致并发症,因为您不知道那里到底发生了什么。因此,此更改应与应用程序代码的工作方式密切相关。
希望这有帮助。
答案 13 :(得分:0)
也许你应该试试ON DELETE CASCADE
答案 14 :(得分:0)
您可以在删除作业之前创建一个触发器来删除引用的行。
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 ;
答案 15 :(得分:0)
此错误Error Code: 1451. Cannot delete or update a parent row: a foreign key constraint fails
的主要问题在于,它不会让您知道哪个表包含 FK故障,因此很难解决冲突。
如果您使用MySQL或类似的软件,我发现您可以为数据库创建一个ER diagram,那么您可以检查并安全地删除任何引发错误的冲突。
connection
database
和tables
答案 16 :(得分:0)
基本上, 这些类型的错误背后的原因是,您最终将尝试删除具有主键(根表)且该主键在子表中用作外键的tupple。 在这种情况下,为了删除父表数据,您必须删除子表数据(使用外键)。 谢谢
答案 17 :(得分:0)
这也发生在我身上,由于其他表的依赖性和引用,我无法删除该条目。我所做的是在表中添加了一个delete列(布尔类型)。该字段中的值显示该项目是否标记为删除。如果标记为删除,则不要获取/使用;否则,请使用它。