我有一个由包含列表(种类)的表组成的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语句会导致问题......
答案 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;
上的工作示例
答案 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
通过这些,您可以修改脚本,这样您就不必每次都放弃动物表。