31

我有以下与 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 NO ACTION

如果子项中存在对父项的引用,我想要 SQL Server 阻止我删除父项?例如,如果有 SubjectId 为 3 的孩子,我希望在 Subject 中删除 subjectID=3 失败。

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

我在问这个问题,就像在一个类似的问题中一样,我的回答是我应该在父母身上定义一个触发器。但是我认为如果存在孩子,只需定义外键就会阻止我删除父母。

4

4 回答 4

53

MSDN上的 column_constraint 页面:

删除时 { 无操作 | 级联 | 设置空 | 默认设置 }

如果这些行具有引用关系并且引用的行已从父表中删除,则指定对更改的表中的行执行什么操作。默认为无操作

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

NO ACTION 意味着当您从 Subject 表删除到 Topic 表时不会发生任何事情。在这种情况下,如果给定的 SubjectId 在 Topic 中有一行,则不能在不破坏参照完整性的情况下从中删除,因此将回滚删除。

更多来自 MSDN:

NO ACTION - SQL Server 数据库引擎引发错误,并且对父表中的行的删除操作被回滚。

于 2013-07-31T17:13:45.430 回答
6

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

于 2013-07-31T18:32:22.030 回答
0

“ON DELETE NO ACTION”实际上与“ON DELETE”相同。

我同意用它来澄清程序员在删除“标题”时对所需操作的想法会很好,并决定如果有与之相关的“行”,则不应删除“标题”。但是,我在 Visual Studio 中定义我的数据库,它拒绝将更改从“ON DELETE”更新为“ON DELETE NO ACTION”。当我刷新它时它仍然是“ON DELETE”。

于 2019-07-24T16:45:39.363 回答
-4

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

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

于 2013-07-31T17:12:45.840 回答