2013-07-31 40 views
8

我有以下DDL,我与SQL Server 2012使用:我是否需要在我的外键上指定ON DELETE NO ACTION?

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 NO ACTION 

我要的是SQL Server停止我删除家长如果给家长参考的孩子存在?例如,我想要删除SubjectID = 3的主题将失败,如果有子项的SubjectId为3.

对此,我不清楚,似乎无法找到答案。我是否需要添加“DELETE NO ACTION”或者我可以不删除这三个词。

我在问这个问题,因为在一个类似的问题中,我有一个回应,我应该定义父级的触发器。不过,我认为只是定义外键将阻止我删除父母,如果一个孩子存在。

回答

19

从column_constraint页面上MSDN

ON DELETE {NO ACTION | CASCADE | SET NULL | SET DEFAULT}

指定如果这些 行具有参照关系,并且从父表中删除引用的行 ,那么表中被更改的行将发生什么操作。缺省值是无动作

所以,如果你愿意,你可以省略ON DELETE NO ACTION,它的工作原理是一样的。

NO ACTION表示当您从主题表中删除主题表时什么都不会发生。在这种情况下,如果在Topic中有一行给定的SubjectId,则不能在不破坏引用完整性的情况下从其中删除,因此Delete将被回滚。

更多来自MSDN:

NO行动 - SQL Server数据库引擎将引发错误,并在父表中的行 删除操作回滚。

+0

Dave - 我很抱歉,但我有点困惑于“指定如果表中被更改的行发生什么操作,如果这些行具有参照关系并且被引用的行从父表中删除。”这是什么意思,因为它涉及我的主题和主题表? – Melina

+0

是主题是父和主题是子表。 – DaveShaw

+0

更新了我的答案。 – DaveShaw

1

您可以删除关键字(这是默认值)

ON DELETE NO ACTION 

会更好,指定这些行动

ON DELETE CASCADE 

下面是详细信息如下:http://msdn.microsoft.com/en-us/library/aa933119%28v=sql.80%29.aspx

你必须写一个触发器,以确保子行不会被删除,因为我不认为SQL Server有这个选项ON DELETE RESTRICT

+0

好吧,那么你说有DELETE NO ACTION是一样的,我没有放任何东西? DELETE RESTRICT是新东西,所以我会试着检查一下。 – Melina

+0

是不是只限制Oracle? – DaveShaw

+0

@DaveShaw Yup,刚刚意识到它,我已经更新了相同的,谢谢 – Akash

1

我会告诉你,虽然你可以跳过删除没有任何操作,但这可能不符合你的最佳利益。在表定义中指定后,可能会阻止某人稍后添加级联删除,因为他们发现您希望这种情况不会发生。当您正确编写所有数据库对象并将它们放在源代码管理中时,这一点尤其如此,代码审查人员会发现存在差异并询问其发生的原因。很多时候,人们太急于添加删除级联并销毁应该保留的数据(例如对于不再有效的客户的财务记录)。他们这样做是因为他们得到的错误不会让他们删除,只是想摆脱它,而不是意识到这是从一个大错误中拯救他们。至少如果您的表脚本中有Delete No Action代码,未来的维护人员会看到这是故意的,而不仅仅是您忘记设置级联删除。当然,如果您的dba不允许级联删除(因为许多人不这样做并且有充分理由!),那么这不是一个潜在的问题,但指定您的意图通常对于可维护性来说是一件好事。

相关问题