如果引用该父项的子实体存在,如何在父项上停止删除?

时间:2013-07-31 16:07:58

标签: sql sql-server

我使用以下与SQL Server 2012一起使用的DDL:

CREATE TABLE Subject (
   [SubjectId] INT IDENTITY (1, 1) NOT NULL,
   [Name] NVARCHAR (50) Not NULL,
   CONSTRAINT [PK_Subject] PRIMARY KEY CLUSTERED ([SubjectId] ASC)
)           

CREATE TABLE Topic (
   [TopicId] INT IDENTITY (1, 1) NOT NULL,
   [Name] NVARCHAR (50) NOT NULL,
   [SubjectId] INT NOT NULL,
   CONSTRAINT [PK_Topic] PRIMARY KEY CLUSTERED ([TopicId] ASC)
)
ALTER TABLE [Topic] WITH CHECK ADD  CONSTRAINT [FK_TopicSubject] 
   FOREIGN KEY([SubjectId]) REFERENCES [Subject] ([SubjectId]) 
   ON DELETE CASCADE

CREATE TABLE SubTopic (
   [SubTopicId] INT IDENTITY (1, 1) NOT NULL,
   [TopicId] INT NOT NULL,
   [Name] NVARCHAR (4000) Not NULL,
   CONSTRAINT [PK_SubTopic] PRIMARY KEY CLUSTERED ([SubTopicId] ASC)
)

ALTER TABLE [SubTopic] WITH CHECK ADD  CONSTRAINT [FK_SubTopicTopic] 
   FOREIGN KEY([TopicId]) REFERENCES [Topic] ([TopicId]) 
   ON DELETE CASCADE

当我尝试运行脚本时,我收到以下消息:

{"Introducing FOREIGN KEY constraint 'FK_TopicSubject' 
on table 'Topic' may cause cycles or multiple cascade paths. 
Specify ON DELETE NO ACTION or ON UPDATE NO ACTION, 
or modify other FOREIGN KEY constraints.\r\nCould not create constraint. 
See previous errors."}

我真正需要的是当一个人试图删除主题时有删除失败的主题。如果我既不包括DELETE ON CASCADE也不包括DELETE NO ACTION,那么这种情况就会发生。如果没有,那么如果有关于该主题的主题,我该如何停止发生主题的删除?

2 个答案:

答案 0 :(得分:1)

简短回答是:如果您不想要级联更新和删除,请使用ON DELETE NO ACTION。同样适用于更新。

以下是来自MSDN article的副本(它的SQL Server 2000,但仍适用相同的规则)

开启删除操作

指定如果尝试使用其他表中现有行中的外键引用的键删除行,则会引发错误并回滚DELETE。

ON UPDATE NO ACTION

指定如果尝试更新其键中的键值被其他表中的现有行引用的行中的键值,则会引发错误并回滚UPDATE。

答案 1 :(得分:0)

请参阅此链接。它已经详细解释了这个错误,并建议创建一个触发器作为替代。 Foreign key constraint may cause cycles or multiple cascade paths?