Sql 如何从包含自引用外键的表中删除数据

Sql 如何从包含自引用外键的表中删除数据,sql,sql-server,sql-server-2005,tsql,Sql,Sql Server,Sql Server 2005,Tsql,这适用于MS SQL 2005服务器。我有一个正在删除表中所有孤立记录的查询。但是,此表具有自引用FKs。我也需要删除这些,但不清楚如何删除。当前脚本将删除所有在其他表中未显示为FK的记录,但我没有考虑其自身表中的自引用FK。表格很简单: PK, FK, DAta 1, NULL, jibberjab 2, 1, jibberjab2 3, 1, skdfasfa 可能最简单的方法是分两步执行,首先删除孤立记录,然后删除第一次删除后现在孤立的引用子项: DELETE FROM TABLE1 W

这适用于MS SQL 2005服务器。我有一个正在删除表中所有孤立记录的查询。但是,此表具有自引用FKs。我也需要删除这些,但不清楚如何删除。当前脚本将删除所有在其他表中未显示为FK的记录,但我没有考虑其自身表中的自引用FK。表格很简单:

PK, FK, DAta
1, NULL, jibberjab
2, 1, jibberjab2
3, 1, skdfasfa

可能最简单的方法是分两步执行,首先删除孤立记录,然后删除第一次删除后现在孤立的引用子项:

DELETE FROM TABLE1
WHERE NOT EXISTS (SELECT 1 FROM TABLE2 WHERE TABLE2.FK = TABLE1.PK)

DELETE FROM TABLE1 
WHERE NOT EXISTS (SELECT 1 FROM TABLE1 B WHERE B.FK = TABLE1.PK)

您可能可以将约束配置为在删除父项时删除:

ALTER TABLE table1 WITH CHECK ADD CONSTRAINT FK_table1_table2 FOREIGN KEY(column1)
REFERENCES table2 (ID) ON DELETE SET NULL -- here
ALTER TABLE table1 CHECK CONSTRAINT FK_table1_table2
GO

如果要有多个级别,可以使用公共表表达式获取需要删除的ID,并在一条语句中处理孤立项及其所有后代:

    WITH cte AS (
        SELECT pk
        FROM myTable
        WHERE id = 1  --pk to delete
        UNION ALL
        SELECT t.pk
        FROM myTable t
        JOIN cte c
            ON t.fk = c.pk
    )
    DELETE t
    FROM cte c
    JOIN myTable t
        ON c.pk = t.pk

您正在尝试删除记录,同时保持自引用完整性。我建议

  • 放弃约束
  • 然后编写查询以删除使用 加入
  • 创建触发器(用于删除)


    我不能截断数据,因为大部分数据都是好的。
    CREATE TRIGGER ON ExTable  
     FOR DELETE  
    AS  
     IF EXISTS (SELECT * FROM ExTable AS tbl   
         JOIN DELETED AS del ON del.FK=tbl1.PK)  
        DELETE FROM ExTable  
          FROM ExTable ex   JOIN DELETED del ON  
            ex.FK=del.ID