• 编写存储过程将异常节点移动到新建的一个节点下


    预期效果

    在这里插入图片描述

    实现代码

    -- 在处理之前,新节点的相关信息已经插入到表中了
    -- 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);
    
  • 相关阅读:
    【TJOI2015】弦论 (后缀数组)
    再见,高中;你好,大学
    我亲爱的朋友们
    将容斥系数隐含在式子中的方法
    一个奇妙的斯特林数推导
    CSP2019游记
    CSP2019初赛游记
    NOI2019游记
    老年选手康复训练
    CTS/APIO2019 游记
  • 原文地址:https://www.cnblogs.com/yldf/p/11900050.html
Copyright © 2020-2023  润新知