zoukankan      html  css  js  c++  java
  • 编写存储过程将异常节点移动到新建的一个节点下

    预期效果

    在这里插入图片描述

    实现代码

    -- 在处理之前,新节点的相关信息已经插入到表中了
    -- 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);
    
  • 相关阅读:
    AGC037F Counting of Subarrays
    AGC025F Addition and Andition
    CF506C Mr. Kitayuta vs. Bamboos
    AGC032D Rotation Sort
    ARC101F Robots and Exits
    AGC032E Modulo Pairing
    CF559E Gerald and Path
    CF685C Optimal Point
    聊聊Mysql索引和redis跳表
    什么是线程安全
  • 原文地址:https://www.cnblogs.com/yldf/p/11900050.html
Copyright © 2011-2022 走看看