reset database无法删除或更新父行:外键约束失败

时间:2013-04-08 19:54:05

标签: mysql reference foreign-keys

我有一个由包含列表(种类)的表组成的sql文件,然后是一个引用该表的主表(动物),如:

DROP    TABLE IF EXISTS `tbl_species`; 
CREATE  TABLE `tbl_species` (
    specie                  VARCHAR(10) PRIMARY KEY
) ENGINE=InnoDB             DEFAULT CHARSET=utf8;
INSERT INTO `tbl_species`   VALUES ('dog');
INSERT INTO `tbl_species`   VALUES ('cat');
INSERT INTO `tbl_species`   VALUES ('bird');

DROP    TABLE IF EXISTS `tbl_animal`; 
CREATE TABLE `tbl_animal` (
    id_animal   INTEGER     NOT NULL PRIMARY KEY AUTO_INCREMENT,
    name        VARCHAR(25) NOT NULL DEFAULT "no nombre",
    specie      VARCHAR(10) NOT NULL DEFAULT "dog",
    FOREIGN KEY (specie)        REFERENCES `tbl_species`     (specie),
    CONSTRAINT `uc_Info_Animal` UNIQUE (`id_animal`)           
) ENGINE=InnoDB                 DEFAULT CHARSET=utf8 AUTO_INCREMENT=1;

这适用于sqlfiddle没有问题,但是当我在服务器上执行sql文件时 我收到以下错误:

Cannot delete or update a parent row: a foreign key constraint fails
Statement:
DROP TABLE IF EXISTS `tbl_species`

请告诉我如何解决这个问题,目前我必须删除数据库并再次创建...所以drop语句会导致问题......

2 个答案:

答案 0 :(得分:5)

您收到Cannot delete or update错误的原因是tbl_animal表已存在。需要按照与创建相反的顺序删除表:

DROP    TABLE IF EXISTS `tbl_animal`; 
DROP    TABLE IF EXISTS `tbl_species`; 

CREATE  TABLE `tbl_species` (
    specie                  VARCHAR(10) PRIMARY KEY
) ENGINE=InnoDB             DEFAULT CHARSET=utf8;
INSERT INTO `tbl_species`   VALUES ('dog');
INSERT INTO `tbl_species`   VALUES ('cat');
INSERT INTO `tbl_species`   VALUES ('bird');

CREATE TABLE `tbl_animal` (
    id_animal   INTEGER     NOT NULL PRIMARY KEY AUTO_INCREMENT,
    name        VARCHAR(25) NOT NULL DEFAULT "no nombre",
    specie      VARCHAR(10) NOT NULL DEFAULT "dog",
    FOREIGN KEY (specie)        REFERENCES `tbl_species`     (specie),
    CONSTRAINT `uc_Info_Animal` UNIQUE (`id_animal`)           
) ENGINE=InnoDB                 DEFAULT CHARSET=utf8 AUTO_INCREMENT=1;

或者,您可以在命令前加上:

SET FOREIGN_KEY_CHECKS=0;

这将禁用当前会话的外键检查。

要重新启用外键检查,请在以后添加以下命令:

SET FOREIGN_KEY_CHECKS=1;

请参阅http://sqlfiddle.com/#!2/b6727

上的工作示例

答案 1 :(得分:1)

您必须在删除从属表之前删除外键表,或者在每次删除表时删除并重新创建外键。

试试这个,每次都会删除并重新创建表:(我的SQL服务器版本是2012)

IF OBJECT_ID('dbo.tbl_animal', 'U') IS NOT NULL
  DROP TABLE dbo.tbl_animal
IF OBJECT_ID('dbo.tbl_species', 'U') IS NOT NULL
  DROP TABLE dbo.tbl_species

CREATE TABLE [dbo].[tbl_species](
    [specie] [varchar](10) NOT NULL,
 CONSTRAINT [PK_tbl_species] PRIMARY KEY CLUSTERED 
(
    [specie] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]

GO

INSERT INTO tbl_species   VALUES ('dog');
INSERT INTO tbl_species   VALUES ('cat');
INSERT INTO tbl_species   VALUES ('bird');

CREATE TABLE [dbo].[tbl_animal](
    [id_animal] [int] IDENTITY(1,1) NOT NULL,
    [name] [varchar](25) NOT NULL,
    [specie] [varchar](10) NOT NULL,
 CONSTRAINT [PK_tbl_animal] PRIMARY KEY CLUSTERED 
(
    [id_animal] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]

GO
ALTER TABLE [dbo].[tbl_animal] ADD  CONSTRAINT [DF_tbl_animal_name]  DEFAULT ('no nombre') FOR [name]
GO
ALTER TABLE [dbo].[tbl_animal] ADD  CONSTRAINT [DF_tbl_animal_specie]  DEFAULT ('dog') FOR [specie]
GO
ALTER TABLE [dbo].[tbl_animal]  WITH CHECK ADD  CONSTRAINT [FK_tbl_animal_tbl_species] FOREIGN KEY([specie])
REFERENCES [dbo].[tbl_species] ([specie])
GO
ALTER TABLE [dbo].[tbl_animal] CHECK CONSTRAINT [FK_tbl_animal_tbl_species]
GO

如果你想试一试,这里有你可以使用的脚本(当表已经存在时): 删除约束,然后表:

ALTER TABLE [dbo].[tbl_animal]  drop CONSTRAINT [FK_tbl_animal_tbl_species] 
GO
IF OBJECT_ID('dbo.tbl_species', 'U') IS NOT NULL
  DROP TABLE dbo.tbl_species
go

删除约束,然后重新创建它:

ALTER TABLE [dbo].[tbl_animal]  drop CONSTRAINT [FK_tbl_animal_tbl_species] 
GO
ALTER TABLE [dbo].[tbl_animal]  WITH CHECK ADD  CONSTRAINT [FK_tbl_animal_tbl_species] FOREIGN KEY([specie])
REFERENCES [dbo].[tbl_species] ([specie])
GO

通过这些,您可以修改脚本,这样您就不必每次都放弃动物表。