回答
当行数不是太大时,erikkallen的递归方法起作用。
这是一个使用临时表来收集所有孩子的选择:
create table #nodes (id int primary key)
insert into #nodes (id) values (@delete_id)
while @@rowcount > 0
insert into #nodes
select distinct child.id
from table child
inner join #nodes parent on child.parentid = parent.id
where child.id not in (select id from #nodes)
delete
from table
where id in (select id from #nodes)
它开始与@delete_id该行并从那里下降。 where语句是为了防止递归;如果你确定没有,你可以把它放弃。
取决于您如何存储您的层次结构。如果您只有ParentID,那么它可能不是您采取的最有效的方法。为了便于操纵子树,你应该有一个附加列Parents
是wouls存储所有父ID,如:
/1/20/25/40
这样你就可以简单地通过获得所有子节点:
where Parents like @NodeParents + '%'
第二种方法
而不仅仅是ParentID您可能也有left
和right
值。以这种方式插入会更慢,但选择操作速度非常快。特别是随着子树节点打交道时... http://en.wikipedia.org/wiki/Tree_traversal
第三种方法
检查递归CTE的,如果你使用SQL 2005+
第四种方法
如果使用SQL 2008,检查HIERARCHYID型。它为您的案例提供了足够的可能性。 http://msdn.microsoft.com/en-us/magazine/cc794278.aspx
添加触发器表中这样
创建mytable上进行删除作为 触发TD_MyTable - 删除的一个子级 从删除d内删除M于D.ID加入myTable的中号 = M.ID
每次删除都会调用同一张表上的删除,反复调用触发器。在线检查书籍是否有其他规则。可能会限制触发器可以嵌套的次数。
ST
取决于您的数据库。如果您使用的是Oracle,你可以做这样的事情:
DELETE FROM Table WHERE ID IN (
SELECT ID FROM Table
START WITH ID = id_to_delete
CONNECT BY PRIOR.ID = ParentID
)
ETA:
没有CONNECT BY,它变得有点棘手。正如其他人所说,触发器或级联删除约束可能是最简单的。
添加外键约束。下面的示例适用于MySQL的(syntax reference):
ALTER TABLE yourTable
ADD CONSTRAINT makeUpAConstraintName
FOREIGN KEY (ParentID) REFERENCES yourTable (ID)
ON DELETE CASCADE;
这将在数据库级别上运行,数据库管理系统将确保一旦行被删除,所有引用行将被删除了。
在SQL Server上:使用递归查询。鉴于CREATE TABLE TMP(ID INT,家长INT),使用
WITH x(Id) AS (
SELECT @Id
UNION ALL
SELECT tmp.Id
FROM tmp
JOIN x ON tmp.Parent = x.Id
)
DELETE tmp
FROM x
JOIN tmp ON tmp.Id = x.Id
你想要的是这些表之间referential integrity。
- 1. 删除分离的数据库SQL 2008
- 2. 从SQL表中删除数据
- 3. 从SQL Server数据库中的所有表数据删除,除了一些表
- 4. 订购父/子 - SQL中的分层数据表
- 5. 单个表中的分层数据
- 6. Linq to SQL的分层数据绑定
- 7. 如何删除MS SQL数据库中的部分重复项?
- 8. 根据sql条件从表中删除
- 9. 删除SQL Server数据库
- 10. 删除数据库SQL PHP
- 11. SQL数据库删除
- 12. 有道创建/更新/删除分层数据
- 13. MVC 5实体框架6 - 删除嵌套/分层数据
- 14. 如何删除SQL CE中表中的所有数据?
- 15. StringTemplate中的分层数据
- 16. ETL中的分层数据
- 17. 充分利用自参照表分层数据在SQL 2005
- 18. 基于分层日期时间的删除T-SQL
- 19. 在Tastypie中表示分层数据
- 20. 从ODBC(SQL Server)中删除数据库名称表列表
- 21. 删除后删除数据表
- 22. 在SQL Server 2008中对表进行层级删除
- 23. 在sql server中删除大量数据
- 24. 删除JLayeredPane中的图层
- 25. 分层数据
- 26. 从SQL表中删除数据的问题
- 27. Java sql - 删除数据库表中的半行
- 28. 删除整个数据库severals表中的SQL安卓
- 29. 如何删除SQL表中的重复数据
- 30. 用SQL Server表中的外键删除数据
NO,我不想整父母链存储在列,因为不断有家长参与改变。并且很难跟踪所有这些。 不能这样做,因为它是现在? – markiz 2009-05-19 12:16:27
什么是您的层次结构数据的主要操作?它是插入,更新还是读取? – 2009-05-19 12:18:09
我倾向于同意第一种方法 - 我们已经得到了我们正在做同样事情的分层数据表。它有助于摆脱孩子,并且如果您需要对树进行基于路径的处理(例如,必须快速返回父母的所有孩子进行计算),这也会有所帮助。 我们最初尝试使用触发器来保持这一点,但真正发现添加大量数据时的性能影响是令人望而却步的。 – 2009-05-19 13:05:18