Using the table ROLE(ROLE_ID, PARENT_ROLE_ID) how can I get all rows that are dependent on another? For example, a root level role will have a null value for [PARENT_ROLE_ID],
-- drop table role;
create table role
( id int not null auto_increment primary key, -- for kicks and if i screw up
roleId int not null, -- i will manually provide it so i can see it
parent int null,
unique index (roleId)
);
insert role(roleId,parent) values (1,null),(2,null),(3,2),(4,3),(5,3),(6,3),(7,4),(8,3),(9,6),(10,6),(11,10);
-- if i want to delete roleId A then i need to delete anything with a parent=A (B) and all of B's lineage too
-- drop procedure deleteParentDownwards;
delimiter $$
create procedure deleteParentDownwards
(
deleteMe int
)
BEGIN
-- deleteMe parameter means i am anywhere in hierarchy of role
-- and i want me and all my offspring deleted (no orphaning of children or theirs)
declare bDoneYet boolean default false;
declare working_on int;
declare theCount int;
CREATE TABLE xxDeleteRoleHierarchyxx
(
roleId int not null,
processed int not null
);
set bDoneYet=false;
insert into xxDeleteRoleHierarchyxx (roleId,processed) select deleteMe,0;
while (!bDoneYet) do
select count(*) into theCount from xxDeleteRoleHierarchyxx where processed=0;
if (theCount=0) then
-- found em all
set bDoneYet=true;
else
-- one not processed yet, insert its children for processing
SELECT roleId INTO working_on FROM xxDeleteRoleHierarchyxx where processed=0 limit 1;
insert into xxDeleteRoleHierarchyxx (roleId,processed)
select roleId,0 from role
where parent=working_on;
-- mark the one we "processed for children" as processed
update xxDeleteRoleHierarchyxx set processed=1 where roleId=working_on;
end if;
end while;
delete from role where roleId in (select roleId from xxDeleteRoleHierarchyxx);
drop table xxDeleteRoleHierarchyxx;
END
$$
call deleteParentDownwards(3); -- deletes many
call deleteParentDownwards(6); -- deletes 4 (assuming line above was not called first!)