2013-04-08 44 views
0

我有引用该表一样通过持有一个列表(种)表形成一个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语句导致问题...

回答

5

你得到Cannot delete or update错误的原因是tbl_animal表已经存在。该表需要在创建相反的顺序进行删除:

SET FOREIGN_KEY_CHECKS=0; 

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

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=1; 

看到http://sqlfiddle.com/#!2/b6727

1

工作的例子你要么有下降的从属表之前删除外键表,或降并在每次删除表时重新创建外键。

试试这个,它会删除并重新创建表每次:(我的SQL Server的版本是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 

用这些你可以修改脚本,所以你不必每次都放弃动物表。

相关问题