簡體   English   中英

觸發以避免刪除該值的最后一行SQL Server

[英]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;

db <>小提琴

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM