我有一個非常簡單的數據庫,其架構定義如下:
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
是導致無引用標籤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'
因為我用的是級聯刪除選項,後從取出dbo.Posts
和記錄從去除dbo.PostTagJunction
。然而,儘管是一個孤兒, dbo.Tags
的hello-world
記錄仍然存在。我也想刪除標籤。怎麼樣?
我應該強調的是,如果標籤被使用的另一篇文章,它不應該被刪除。謝謝。
我正在使用Dapper
和C#
與數據庫進行通信。
通過使用級聯選項刪除子表記錄,無法刪除父表記錄。創建一個新的存儲過程Posts, Tags, PostTagJunction
基於從C#應用程序作為參數傳遞的PostSlug ( @PostSlug
)刪除Posts, Tags, PostTagJunction
。
刪除PostTagJunction
表中的Cascading約束並嘗試這樣的操作。
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
希望這可以幫助。
您可以使用觸發器對數據庫進行非規範化,換句話說,您可以在dbo.Posts
上創建一個FOR DELETE
觸發器,它將自動刪除孤立dbo.Tags
表中的記錄,例如:
CREATE TRIGGER triggerName
ON dbo.Posts
FOR DELETE
AS
DELETE FROM dbo.Tags
WHERE TagName IN (SELECT TagName FROM DELETED)
GO