2013-07-31 20 views
0

我有以下DDL,我与SQL Server 2012使用:如果引用该父项的子实体存在,如何停止对父项的删除?

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,也会发生这种情况。如果不是,那么如果有关于该主题的主题,如何才能停止主题上的删除?

+0

我看这几个地方后仍不清楚。 “ON DELETE NO ACTION”与我在该行中没有包含DELETE的任何内容有区别吗? – Melina

回答

1

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

+1

另外我想补充一点,你会得到这个错误,因为当你从主题表中删除一行时,SQL服务器将从主题表中删除一行(在删除级联上),然后它会尝试从行中删除一行子主题表。所以在这里您可以看到系统正在计算级联路径,并避免任何最坏情况下它试图避免任何多级Cascade。 – Sonam

+0

感谢您的解释。如果我没有“ON DELETE CASCADE”,并且当我尝试删除主题时主题表中仍有某些内容,那么这会导致错误并导致DELETE失败? – Melina

+0

我是否需要“ON DELETE CASCADE”或“ON DELETE NO ACTION”我可以不拥有吗? – Melina

0

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

这里是MSDN article(这是SQL Server 2000的,但同样的规则仍然适用)

ON DELETE NO ACTION

指定副本,如果试图删除行与国外引用的关键键在其他表中的现有行中,则会引发错误并回滚DELETE。

ON UPDATE NO ACTION

指定如果试图更新的行,其关键是通过外键与现有的其它表行引用的键值,产生一个错误,并且更新推出背部。

相关问题