我需要在外键上指定ON DELETE NO ACTION吗?
技术问答
231 人阅读
|
0 人回复
|
2023-09-14
|
我有以下用于SQL Server 2012的DDL:3 y6 w8 p& g: J* F# ^/ \
CREATE TABLE Subject (% m( [8 l9 N# }( D; |
[SubjectId] INT IDENTITY (1, 1) NOT NULL,# N0 Z& p$ |9 g7 E5 K3 q" B5 p+ I
[Name] NVARCHAR (50) Not NULL," ]% Z5 d3 ~) O. S; X
CONSTRAINT [PK_Subject] PRIMARY KEY CLUSTERED ([SubjectId] ASC); u# h$ l6 s+ \! {5 Y
)+ U4 B1 v5 I2 n$ C9 M4 z$ p+ Y) I
CREATE TABLE Topic (. H" z) |/ k% U; q: k& x
[TopicId] INT IDENTITY (1, 1) NOT NULL,. g2 ?) U4 s, ^# ^4 ?: j z% `
[Name] NVARCHAR (50) NOT NULL,% W2 C0 z' i+ C
[SubjectId] INT NOT NULL,
0 C: G9 ^7 G% s+ Q CONSTRAINT [PK_Topic] PRIMARY KEY CLUSTERED ([TopicId] ASC)
/ |2 e% k* F7 ` o- n0 X)
1 k3 T2 ?: c8 h: Q( xALTER TABLE [Topic] WITH CHECK ADD CONSTRAINT [FK_TopicSubject] 1 h9 U. Y2 h# E4 _/ L7 R
FOREIGN KEY([SubjectId]) REFERENCES [Subject] ([SubjectId])
& E% L; `" m! a; e1 N ON DELETE NO ACTION
) d1 d4 ], E6 u6 g3 `4 c- C0 L如果子级中存在对该父级的引用,我想让SQL Server阻止我删除该父级吗?例如,如果有SubjectId为3的子代,我希望删除SubjectID =. e& P) A6 T- T4 \1 n
3上的Subject失败。9 G# F j( J8 K& z0 ^
为此,我不清楚,似乎找不到答案。我需要添加“删除不采取任何行动”还是可以不删除这三个词?
2 o' Q( A3 b) H ]/ I( K# f我问这个问题,就像在一个类似的问题中,我有一个响应,我应该在父级上定义一个触发器。但是,我认为仅定义外键将阻止我删除存在子代的父代。
. [$ F/ P5 _& O: p& j4 ^$ j$ N* o6 a5 R
, ^' ?+ G1 ~% {" _0 K p& `解决方案:: P" k; P3 _* j7 a4 t! |* n
7 h( ?% e2 `; ?) ~6 Q8 o0 G3 R0 Q
% S! W$ b5 K) b! Q5 y1 [
/ S* s5 a U% Q0 Y$ U+ i 从MSDN上的column_constraint页面:
5 E! D5 v+ o9 d7 }) f! m" T
+ \$ B+ C0 Q' G* h" c" w# E删除后{无动作| 级联| SET NULL | 默认设置 }% U8 l& Z9 {5 N- D
指定如果更改后的表中的行具有引用关系并且从父表中删除了被引用的行,将对这些行执行什么操作。默认值为 NO ACTION 。, r9 k/ L) t+ h9 e% }6 f+ R- N
: }: ^) c$ {% c: c' f1 l
因此,ON DELETE NO ACTION如果您愿意,可以略过而已,它的工作原理相同。5 O( w" Q( r; g) s, B r4 d
NO
* o0 J- z. \' s# U4 ]9 `8 hACTION表示从主题表删除到主题表时什么也不会发生。在这种情况下,如果“主题”中有给定SubjectId的行,则您不能在不破坏参照完整性的情况下将其删除,因此Delete将回滚。# f- C2 W$ A0 `, ?( @, n
来自MSDN的更多信息: X) o' ^: {2 C; n
- w* I! f8 P* N1 V$ U: W" D' g
无操作-SQL Server数据库引擎引发错误,并且对父表中的行的删除操作将回滚。 |
|
|
|
|
|