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语句导致问题......

4

2 回答 2

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上的工作示例

于 2013-04-08T20:03:04.217 回答
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

有了这些,您可以修改脚本,这样您就不必每次都删除动物表。

于 2013-04-08T20:22:46.640 回答