高级级联删除

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 使用,则应该 而不是 将其删除。谢谢。

我正在使用 DapperC# 与数据库通信。

您可以使用触发器对数据库进行反规范化,换句话说,您可以在 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

希望对您有所帮助。