删除引用自己的表上的所有子项

时间:2019-09-21 17:48:20

标签: sql sql-server

假设我们有一个看起来像这样的表:

class ProjectTableViewCell: UITableViewCell {
    @IBOutlet private weak var collectionView: UICollectionView!

    var projects: [Project] = []
    let nc = NotificationCenter.default
    let projectsNotification = Notification.Name(rawValue: "projectsDataNotification")

    override func awakeFromNib() {
        super.awakeFromNib()
        collectionView.dataSource = self
        collectionView.delegate = self

        let flowLayout = UICollectionViewFlowLayout()
        flowLayout.scrollDirection = .horizontal
        flowLayout.minimumLineSpacing = 10.0
        flowLayout.minimumInteritemSpacing = 10.0
        collectionView.collectionViewLayout = flowLayout

        nc.addObserver(self, selector: #selector(self.populateProjects), name: projectsNotification, object: nil)
    }

    @objc func populateProjects(notification: Notification) {
        let userInfo: [String: Any] = notification.userInfo as! [String : Any]
        let projectsData = userInfo["projects"] as! [Project]
        self.projects = projectsData

        for project in projectsData {
            print("TEST projectsData TableCell: \(project.title)")
        }
    }
}

extension ProjectTableViewCell: UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return projects[section].needs.count
    }

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "needsCell", for: indexPath)

        let cellLayer = cell.layer
        cellLayer.borderWidth = 0.75
        cellLayer.cornerRadius = 6

        return cell
    }

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
        return CGSize(width: 75, height: 30)
    }  
}

在此表中,我们有一个数据层次结构,可能看起来像这样:

CREATE TABLE Test
(
    Id INT NOT NULL PRIMARY KEY IDENTITY(1,1),
    [Name] NVARCHAR(50) NOT NULL,
    ParentId INT NULL FOREIGN KEY REFERENCES Test(Id)
)

如何在不使用级联删除的情况下删除id 1及其所有子级?

1 个答案:

答案 0 :(得分:1)

您将必须使用rCTE(递归公用表表达式)通过层次结构进行递归。然后,您可以JOIN将这些数据添加到表中并删除相关的行:

DECLARE @ID int = 1;

WITH rCTE AS(
    SELECT T.Id
    FROM dbo.Test T
    WHERE T.Id = @ID
    UNION ALL
    SELECT T.Id
    FROM rCTE r
         JOIN dbo.Test T ON r.Id = T.ParentId)
DELETE T
FROM dbo.Test T
     JOIN rCTe r ON T.Id = r.Id;

请注意,与您可能看到的某些示例不同,例如使用CTE DELETE复制行,rCTE不可更新(由于使用UNION)。因此,您不能简单地在末尾(DELETE)上对CTE执行DELETE FROM rCTE操作,而必须将其用作JOIN

DB<>Fiddle