Sqlserver
 sql >> база данни >  >> RDS >> Sqlserver

При каскада за изтриване за таблица за саморефериране

Ако приемем, че запазвате своя FOREIGN KEY ограничение на място, не можете да отстраните проблема в FOR DELETE задействане. FOR тригери (известни също като AFTER тригери) стреля след дейността е осъществена. А външният ключ ще предотврати ред да бъде изтрит, ако има препратки. Проверките на външния ключ се извършват преди изтриване.

Това, от което се нуждаете, е INSTEAD OF задействане. Също така трябва да имате предвид, че текущото ви задействане се е опитало да се справи само с едно "ниво" на препращане. (И така, ако ред 3 препраща към ред 2 и ред 2 препраща към ред 1 и вие изтриете ред 1, вашето задействане само се опита да премахне ред 2)

И така, нещо като:

CREATE TRIGGER [dbo].[T_comment_Trigger]
    ON [dbo].[Comments]
    INSTEAD OF DELETE
AS
    ;WITH IDs as (
       select id from deleted
       union all
       select c.id
       from Comments c
              inner join
            IDs i
              on
                 c.ParentID = i.id
    )
    DELETE FROM Comments
    WHERE id in (select id from IDs);

Ако има други каскадни ограничения на външния ключ (без саморефериране), всички те трябва да бъдат заменени с действия в този тригер. В такъв случай бих препоръчал въвеждането на променлива на таблица, която да съхранява списъка с всички идентификатори, които в крайна сметка ще бъдат изтрити от Comments таблица:

CREATE TRIGGER [dbo].[T_comment_Trigger]
    ON [dbo].[Comments]
    INSTEAD OF DELETE
AS
    declare @deletions table (ID varchar(7) not null);
    ;WITH IDs as (
       select id from deleted
       union all
       select c.id
       from Comments c
              inner join
            IDs i
              on
                 c.ParentID = i.id
    )
    insert into @deletions(ID)
    select ID from IDs

    DELETE FROM OtherTable
    WHERE CommentID in (select ID from @deletions)

    --This delete comes last
    DELETE FROM Comments
    WHERE id in (select ID from @deletions);



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Разгледайте причините и решенията за повреда в базата данни на SQL Server

  2. Присъединяване към MAX запис за дата в групата

  3. Демистификация на CXPACKET и CXCONSUMER типовете чакане в SQL Server

  4. Сравнете DATETIME и DATE, пренебрегвайки частта от времето

  5. неразрешена препратка към обект [INFORMATION_SCHEMA].[TABLES]