Reputation: 360
Having this table:
I want to delete the root node, by sending a query ID=1 and I want that all the subnodes of this id will be deleted as well.
how can I do it?
Upvotes: 0
Views: 664
Reputation:
This can be done using a recursive common table expression.
To get all children of one node you can use:
with tree as (
select id, parent
from eyalewin
where id = 1
union all
select c.id, c.parent
from eyalewin c
join tree p on p.id = c.parent
)
select *
from tree;
This can then be used to delete all of them:
with tree as (
select id, parent
from eyalewin
where id = 1
union all
select c.id, c.parent
from eyalewin c
join tree p on p.id = c.parent
)
delete from eyalewin
where id in (select id
from tree);
Upvotes: 3
Reputation: 43636
Let's say you have the following data:
and you want to delete record 2.1
and all of his descendants (in this case 2.1.3
only). You can use the following code to get the IDs
that needs to be deleted:
WITH DataSource ([ID], [HierarchyLevel]) AS
(
SELECT [ID]
,CAST(REPLACE('/' + [Name] + '/', '.', '/') AS HIERARCHYID)
FROM @DataSource
)
SELECT [ID]
,[HierarchyLevel].ToString()
FROM DataSource
WHERE [HierarchyLevel].IsDescendantOf('/2/1/') = 1;
Basically, we convert your record to hierarchy id
type and use the build-in IsDescendantOf function to get all childs
of the node.
This is full working example:
DECLARE @DataSource TABLE
(
[ID] TINYINT
,[Name] VARCHAR(12)
,[Owner] VARCHAR(12)
,[Parent] INT
);
INSERT INTO @DataSource ([ID], [Name], [Owner], [Parent])
VALUES (1, '1', '1', NULL)
,(2, '1.1', '1.1', 1)
,(3, '1.1.1', '1.1.1', 2)
,(4, '2', '2.1', NULL)
,(5, '2.1', '2.1', 4)
,(6, '2.2', '2.2', 4)
,(7, '2.1.3', '2.1.3', 5);
WITH DataSource ([ID], [HierarchyLevel]) AS
(
SELECT [ID]
,CAST(REPLACE('/' + [Name] + '/', '.', '/') AS HIERARCHYID)
FROM @DataSource
)
DELETE @DataSource
FROM @DataSource DS
INNER JOIN DataSource DS1
ON DS.[ID] = DS1.[ID]
WHERE [HierarchyLevel].IsDescendantOf('/2/1/') = 1;
SELECT *
FROM @DataSource;
Upvotes: 2