SQL Server 级联
Posted
技术标签:
【中文标题】SQL Server 级联【英文标题】:SQL Server Cascading 【发布时间】:2010-10-06 16:48:52 【问题描述】:我正在创建一个网站,用户可以在其中发布“帖子”,然后用户可以对这些帖子进行“评论”。我有一个包含 3 个表的数据库。一个包含用户信息,一个包含发布信息,最后一个包含评论信息。
我想设置规则,以便如果删除用户,则删除其所有帖子和 cmets,如果用户删除其中一个帖子,则删除所有关联的 cmets。但是,这会设置“多个 CASCADE 路径”。
我一直在寻找解决方案,并找到了一些关于触发器的信息。它们会是最好的使用方法吗?如果我使用它们,我是否必须更改所有 CASCADE 以由触发器完成?
谢谢
克莱夫斯特
【问题讨论】:
【参考方案1】:使用声明性引用完整性。
create table foo
(
id int not null primary key ,
foo varchar(32) not null ,
)
create table bar
(
id int not null primary key ,
foo_id int null foreign key references foo ( id ) on delete cascade ,
)
从 foo 中删除一行将删除 bar 中所有相关的行。
但要小心级联删除——胖手指删除语句会很快造成大量损坏,这与 *nix 中的 rm(1) 不同。如果您一举删除大量数据,级联删除也会很快破坏您的事务日志。
【讨论】:
感谢您的回复。我是 SQL 初学者。是否可以在 SQL Server Management Studios 的“关系...”选项中进行设置? 在 SQL Server Management Studio 中定义外键约束时,可以选择删除或更新相关主键值时要执行的引用操作(但你应该学会写改为 DDL(CREATE/ALTER 语句)。它使您的架构在源代码控制下 [b]much[/b] 更简单。【参考方案2】:另一种选择是创建两个专用的存储过程,根据需要执行这些删除步骤
CREATE PROCEDURE dbo.DeleteUser @UserID VARCHAR(50)
AS BEGIN
DELETE FROM dbo.Comments
WHERE Author = @UserID
DELETE FROM dbo.Posts
WHERE Author = @UserID
DELETE FROM dbo.User
WHERE UserID = @UserID
END
第二条规则:
CREATE PROCEDURE dbo.DeletePost @PostID INT
AS BEGIN
DELETE FROM dbo.Comments
WHERE PostID = @PostID
DELETE FROM dbo.Posts
WHERE ID = @PostID
END
在这种情况下,您可以完全控制实际发生的事情,级联删除不会带来意外的惊喜,也不需要使用触发器。
【讨论】:
这就是我要找的。谢谢。【参考方案3】:我认为这可以很容易地设置,不会出现您遇到的错误,也无需使用触发器,如下所示:
1) The foreign key between Users and Posts should be set up to be cascade delete
2) The foreign key between Posts and Comments should be set up to be cascade delete
【讨论】:
感谢您的回复。我已经考虑过这一点,但是如果创建帖子的用户之外的用户是 cmets。如果他们的帐户被删除,那么您的解决方案不会删除他们的评论以上是关于SQL Server 级联的主要内容,如果未能解决你的问题,请参考以下文章