高级级联删除
Advanced cascade delete
我有一个非常简单的数据库,其架构定义如下:
CREATE TABLE dbo.Tags
(
TagName NVARCHAR(100) PRIMARY KEY
);
CREATE TABLE dbo.Posts
(
PostSlug NVARCHAR(100) PRIMARY KEY,
Title NVARCHAR(100) NOT NULL
);
CREATE TABLE dbo.PostTagJunction
(
PostSlug NVARCHAR(100),
TagName NVARCHAR(100)
PRIMARY KEY (PostSlug, TagName),
FOREIGN KEY (PostSlug) REFERENCES dbo.Posts (PostSlug)
ON DELETE CASCADE,
FOREIGN KEY (TagName) REFERENCES dbo.Tags (TagName)
);
我想这样做,以便当我从 dbo.Posts
中删除 post 时,dbo.Tags
中生成的未引用标签也会被删除。
考虑以下代码:
INSERT INTO dbo.Posts
VALUES ('hello-world', 'Hello World');
INSERT INTO dbo.Tags
VALUES ('Introduction');
INSERT INTO dbo.PostTagJunction
VALUES ('hello-world', 'Introduction');
DELETE
FROM dbo.Posts
WHERE postslug = 'hello-world'
因为我使用级联删除选项,post 从 dbo.Posts
中删除,记录从 dbo.PostTagJunction
中删除。然而,尽管是孤儿,dbo.Tags
中的 hello-world
记录仍然存在。我也想删除标签。如何?
我要强调的是,如果标签正在被另一个 post 使用,则应该 而不是 将其删除。谢谢。
我正在使用 Dapper
和 C#
与数据库通信。
您可以使用触发器对数据库进行反规范化,换句话说,您可以在 dbo.Posts
上创建一个 FOR DELETE
触发器,它会自动删除您在孤立 dbo.Tags
[=16] 中的记录=], 例子:
CREATE TRIGGER triggerName
ON dbo.Posts
FOR DELETE
AS
DELETE FROM dbo.Tags
WHERE TagName IN (SELECT TagName FROM DELETED)
GO
无法通过使用级联选项删除子 table 记录来删除父 table 记录。基于从 C# 应用程序作为参数传递的 PostSlug (@PostSlug
) 创建一个新的存储过程以删除 Posts, Tags, PostTagJunction
。
在 PostTagJunction
table 中删除级联约束并尝试类似的操作。
DECLARE @PostSlug NVARCHAR(100) = 'hello-world'
DECLARE @TagName NVARCHAR(100) = ''
SELECT @TagName= TagName FROM PostTagJunction WHERE PostSlug =@PostSlug
DELETE PostTagJunction WHERE PostSlug =@PostSlug
IF NOT EXISTS(SELECT 1 FROM PostTagJunction WHERE TagName =@TagName)
DELETE Tags WHERE TagName =@TagName
DELETE Posts WHERE PostSlug =@PostSlug
希望对您有所帮助。
我有一个非常简单的数据库,其架构定义如下:
CREATE TABLE dbo.Tags
(
TagName NVARCHAR(100) PRIMARY KEY
);
CREATE TABLE dbo.Posts
(
PostSlug NVARCHAR(100) PRIMARY KEY,
Title NVARCHAR(100) NOT NULL
);
CREATE TABLE dbo.PostTagJunction
(
PostSlug NVARCHAR(100),
TagName NVARCHAR(100)
PRIMARY KEY (PostSlug, TagName),
FOREIGN KEY (PostSlug) REFERENCES dbo.Posts (PostSlug)
ON DELETE CASCADE,
FOREIGN KEY (TagName) REFERENCES dbo.Tags (TagName)
);
我想这样做,以便当我从 dbo.Posts
中删除 post 时,dbo.Tags
中生成的未引用标签也会被删除。
考虑以下代码:
INSERT INTO dbo.Posts
VALUES ('hello-world', 'Hello World');
INSERT INTO dbo.Tags
VALUES ('Introduction');
INSERT INTO dbo.PostTagJunction
VALUES ('hello-world', 'Introduction');
DELETE
FROM dbo.Posts
WHERE postslug = 'hello-world'
因为我使用级联删除选项,post 从 dbo.Posts
中删除,记录从 dbo.PostTagJunction
中删除。然而,尽管是孤儿,dbo.Tags
中的 hello-world
记录仍然存在。我也想删除标签。如何?
我要强调的是,如果标签正在被另一个 post 使用,则应该 而不是 将其删除。谢谢。
我正在使用 Dapper
和 C#
与数据库通信。
您可以使用触发器对数据库进行反规范化,换句话说,您可以在 dbo.Posts
上创建一个 FOR DELETE
触发器,它会自动删除您在孤立 dbo.Tags
[=16] 中的记录=], 例子:
CREATE TRIGGER triggerName
ON dbo.Posts
FOR DELETE
AS
DELETE FROM dbo.Tags
WHERE TagName IN (SELECT TagName FROM DELETED)
GO
无法通过使用级联选项删除子 table 记录来删除父 table 记录。基于从 C# 应用程序作为参数传递的 PostSlug (@PostSlug
) 创建一个新的存储过程以删除 Posts, Tags, PostTagJunction
。
在 PostTagJunction
table 中删除级联约束并尝试类似的操作。
DECLARE @PostSlug NVARCHAR(100) = 'hello-world'
DECLARE @TagName NVARCHAR(100) = ''
SELECT @TagName= TagName FROM PostTagJunction WHERE PostSlug =@PostSlug
DELETE PostTagJunction WHERE PostSlug =@PostSlug
IF NOT EXISTS(SELECT 1 FROM PostTagJunction WHERE TagName =@TagName)
DELETE Tags WHERE TagName =@TagName
DELETE Posts WHERE PostSlug =@PostSlug
希望对您有所帮助。