预期效果
实现代码
-- 在处理之前,新节点的相关信息已经插入到表中了
-- v_normal_node_res_id: 唯一正常的节点的res_id
-- v_new_node_res_id: 新建的节点的res_id
-- 功能:将异常节点及其子节点移动到新建的一个节点,作为其子节点
-- 注意:需要获取新节点的级别,比如说为3
--则需要做的操作如下:
/*
(1)找到需要更新的记录
a.排除正常节点及其子节点 特点:res_tree_level3_id=v_normal_node_res_id
b.排除新节点 特点:res_tree_level3_id=v_new_node_res_id
c.排除一二级节点 特点:res_tree_level3_id=0
(2)更新记录:需要更新哪些字段(以下是针对需要更新的节点)
a.对于与新节点同级别的节点,需要将其parent_res_id设置为新节点的res_id
b.对于所有节点,需要更新
设置res_level:= res_level + 1;
res_tree_level3_id := 新节点的res_id
res_tree_level4_id :=res_tree_level3_id
res_tree_level5_id :=res_tree_level4_id
。。。
res_tree_level12_id:=res_tree_level1_id
直到该节点的res_level,都要进行更新
实际的写代码的时候,需要逆序复制,否则值会被覆盖
*/
create or replace function func_move_abnormal_node_to_new_node(v_normal_node_res_id imos_id, v_new_node_res_id imos_id)
returns integer
as
$BODY$
declare
v_rec_tbl_res RECORD; -- 存储当前节点信息
v_current_node_res_id imos_id; -- 当前节点res_id
v_current_node_res_level int32; -- 当前节点res_level
v_tmp_counter int:=0; -- 计数器
v_str_sql_cmd text; -- 暂存动态SQL
v_str_cmd text; -- 暂存动态SQL
v_int_level_of_new_node int:=0; -- 新节点的级别,也等于正常节点的级别
v_rec record;
begin
select res_level into v_int_level_of_new_node from tbl_res where res_id=v_new_node_res_id; -- 获取新节点的级别res_level==正常节点的级别
v_str_cmd = 'select res_id, res_level from tbl_res ';
v_str_cmd = v_str_cmd || ' where res_tree_level'||v_int_level_of_new_node||'_id <> ' || v_normal_node_res_id ; --去除正常节点及其子节点
v_str_cmd = v_str_cmd || ' and res_tree_level' ||v_int_level_of_new_node||'_id <> 0 '; --去除一级、二..v_int_level_of_new_node-1级节点
v_str_cmd = v_str_cmd || ' and res_tree_level' ||v_int_level_of_new_node||'_id <> ' || v_new_node_res_id ; --去除新上任的v_int_level_of_new_node级节点
--修改parent_res_id
for v_rec in (select res_id from tbl_res where res_level=v_int_level_of_new_node and res_id<>v_new_node_res_id and res_id <> v_normal_node_res_id )
loop
update tbl_res set parent_res_id=v_new_node_res_id where res_id=v_rec.res_id;
end loop;
-- 获取哪些记录需要进行处理
for v_rec_tbl_res in execute v_str_cmd
loop
-- 获取当前节点res_id
v_current_node_res_id=v_rec_tbl_res.res_id;
-- 更新新节点同级 & 异常节点的parent_res_id为v_new_node_res_id
-- 更新当前节点res_tree_level[v_int_level_of_new_node]~res_tree_level[v_rec_tbl_res.res_level+1]以及res_level
v_tmp_counter=v_rec_tbl_res.res_level+1;
v_str_sql_cmd='update tbl_res set ';
while v_tmp_counter > v_int_level_of_new_node
loop
v_str_sql_cmd = v_str_sql_cmd ||'res_tree_level'|| v_tmp_counter || '_id = res_tree_level' || (v_tmp_counter-1) || '_id,' ;
v_tmp_counter = v_tmp_counter -1;
end loop;
v_str_sql_cmd = v_str_sql_cmd || 'res_level=res_level+1, res_tree_level'||v_int_level_of_new_node||'_id='||v_new_node_res_id;
v_str_sql_cmd = v_str_sql_cmd || ' where res_id = '|| v_current_node_res_id|| '; ';
execute v_str_sql_cmd;
end loop;
return 0;
end;
$BODY$
language plpgsql ;
-- select * from tbl_res;
-- select * from func_move_abnormal_node_to_new_node(10023,10024);