[英]Trigger to Avoid Deletion of Last Row of that Value SQL Server
所以我需要一些幫助,我需要創建一個避免刪除值的最后一行的觸發器
假設我有:
SubjectID | ModuleNr
1792 | 1
1792 | 2
1222 | 3
我希望能夠避免刪除每個SubjectID的最后一行,因此在這種情況下,只會刪除第一行。
我嘗試了不同的方法(使用SQL Server 2012
),但是我不能在FOR DELETE之后使用For Each,也不能在Delete之前執行。
無論如何,我嘗試的每種方法都讓我刪除了該行。
請記住,這是我在SQL的第一學期,這是我的新手。
這是我嘗試使用count以某種方式查看是否只有1個值:
CREATE TRIGGER curriculum.Keep_Last_Module
ON curriculum.Module
FOR DELETE
AS
BEGIN
DECLARE @count AS INT
SET @count = (SELECT COUNT(*) FROM curriculum.Module
WHERE SubjectID = (SELECT SubjectID FROM deleted) GROUP BY SubjectID)
IF (@count = 1)
BEGIN
RAISERROR('Last Module Cannot be Erased',16, 1)
END
END
先感謝您
我使用了下面的觸發器,它在刪除一行時非常有效,在刪除多行的情況下,如果一個subjectID違反此條件,它將阻止整個刪除操作:
CREATE TRIGGER curriculum.Keep_Last_Module
ON curriculum.Module
FOR DELETE
AS
BEGIN
If exists(SELECT SubjectID FROM deleted except SELECT SubjectID FROM curriculum.module)
BEGIN
RAISERROR('Last Module Cannot be Erased',16, 1)
ROLLBACK
END
END
END
似乎您希望它在某個主題的所有行都將被刪除的情況下自動保留一個。
為此,您需要一個INSTEAD OF
觸發器,例如以下示例( DEMO )
CREATE TRIGGER curriculum.Keep_Last_Module
ON curriculum.Module
INSTEAD OF DELETE
AS
BEGIN
WITH T
AS (SELECT *,
COUNT(*) OVER (PARTITION BY SubjectID) AS BaseSubjectCount
FROM curriculum.Module),
D
AS (SELECT *,
COUNT(*) OVER ( PARTITION BY SubjectID) AS DeletedSubjectCount,
MAX(ModuleNr) OVER (PARTITION BY SubjectID) AS MAXModuleNr
FROM deleted)
DELETE T
FROM T
JOIN D
ON T.SubjectID = d.SubjectID
AND T.ModuleNr = d.ModuleNr
AND ( T.BaseSubjectCount <> D.DeletedSubjectCount
OR D.ModuleNr <> D.MAXModuleNr );
IF @@ROWCOUNT < (SELECT COUNT(*) FROM deleted)
PRINT 'At least one row was ignored as that would remove the last one for a SubjectID'
END
您希望每個主題至少保留一行。 計算“之前”和“之后”的主題數:
CREATE TRIGGER curriculum.Keep_Last_Module
ON curriculum.Module
INSTEAD OF DELETE
AS
BEGIN
DECLARE @beforeSubjects INT;
DECLARE @afterSubjects INT;
SELECT @beforeSubjects = COUNT(DISTINCT m.subject),
@afterSubjects = COUNT(DISTINCT CASE WHEN d.ModuleNR IS NULL THEN m.subject END)
FROM curriculum.Module m LEFT JOIN
deleted d
ON m.ModuleNr = d.ModuleNr
IF (@beforeSubjects <> @afterSubjects)
BEGIN
RAISERROR('Last Module Cannot be Erased', 16, 1)
END;
DELETE m
FROM curriculum.module m JOIN
deleted d
ON m.ModuleNr = d.ModuleNr;
END;
您可以檢查是否連續deleted
存在這沒有記錄module
為同一subjectid
存在,具有更大的modulenr
。
CREATE TRIGGER keep_last_module
ON module
FOR DELETE
AS
BEGIN
IF EXISTS (SELECT *
FROM deleted d
WHERE NOT EXISTS (SELECT *
FROM module m
WHERE m.subjectid = d.subjectid
AND m.modulenr > d.modulenr))
BEGIN
THROW 50000, 'The last module cannot be deleted.', 0;
END;
END;
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.