根据传过来的表名和关系字段名可以动态找到某个某一个节点的所有父节点或者子节点
辅助方法
CREATE FUNCTION `func_get_split_string`(`f_string` varchar(1000), `f_delimiter` varchar(5), `f_order` int)
RETURNS varchar(255) CHARSET utf8
LANGUAGE SQL
NOT DETERMINISTIC
CONTAINS SQL
SQL SECURITY DEFINER
COMMENT ''
BEGIN
#592876
#f_string字符串按f_delimiter截取后获取第f_order位
declare result varchar(255) default '';
declare oneSub varchar(255) default '';
declare cou int default 0;
set cou=1+(length(f_string) - length(replace(f_string,f_delimiter,'')));
if f_order>cou then
return result;
end if;
set result = reverse(substring_index(reverse(substring_index(f_string,f_delimiter,f_order)),f_delimiter,1));
return result;
END
子存储过程
CREATE PROCEDURE `pro_find_tree_recursion`(IN `table_name` VARCHAR(50), IN `parent_name` VARCHAR(50), IN `id_name` VARCHAR(50), IN `self_value` VARCHAR(50), INOUT `rt_value` MEDIUMTEXT)
LANGUAGE SQL
NOT DETERMINISTIC
CONTAINS SQL
SQL SECURITY DEFINER
COMMENT ''
recur:BEGIN
DECLARE done INT DEFAULT 0;
DECLARE b VARCHAR (32);
DECLARE all_value VARCHAR (1000);
DECLARE tree_sql1 VARCHAR (1000);
DECLARE cou INT default 0;
DECLARE ALL_VALUE_COU INT default 0;
DECLARE one_value VARCHAR (100);
DECLARE max_loop INT DEFAULT 0;
DECLARE now_loop INT DEFAULT 0;
set @@session.max_sp_recursion_depth=20;
#现将自己塞进来
if length(rt_value)=0 or rt_value is null
then
set rt_value=concat(self_value);
else
set rt_value=concat(rt_value,';',self_value);
end if;
#查找出自己所有的下级
set tree_sql1= concat('select GROUP_CONCAT(',id_name,') into @l_value ',/*,id_name,' into @l_id','*/'from ',table_name,' t where t.',parent_name,' = ',self_value);
#select tree_sql1;
set @tree_sql1=tree_sql1;
prepare stmt from @tree_sql1;
EXECUTE stmt;
deallocate prepare stmt;
set all_value=@l_value;
#如果没有下级,返回上一层
if length(all_value)=0 or all_value is null
then
leave recur;
end if;
#如果有下级,则继续循环
rec_while :while 1=1
do
set now_loop=now_loop+1;
set one_value=func_get_split_string(all_value,',',now_loop);
if length(one_value)=0 or one_value is null then
#下级循环结束,返回上一层
leave rec_while;
end if;
#继续找下级的子节点
call pro_find_tree_recursion(table_name,parent_name,id_name,one_value,rt_value);
end while;
leave recur;
END
主存储过程
CREATE PROCEDURE `pro_find_tree_value`(IN `schema_name` VARCHAR(50), IN `table_name` VARCHAR(50), IN `type` INT, IN `self_value` VARCHAR(50), IN `id_name` VARCHAR(50), IN `self_name` VARCHAR(50), IN `parent_name` VARCHAR(50), IN `recure_num` INT, INOUT `rt_value` MEDIUMTEXT)
LANGUAGE SQL
NOT DETERMINISTIC
CONTAINS SQL
SQL SECURITY DEFINER
COMMENT ''
pro_begin:BEGIN
DECLARE _value varchar(100);
DECLARE rtValue text default '';
DECLARE _schema varchar(100);
DECLARE cou int;
DECLARE tree_sql1 VARCHAR(500);
DECLARE id_value varchar(100);
if length(schema_name)=0
then select database() into _schema;
else set _schema=schema_name ;
end if;
select count(1) into cou
from information_schema.columns a where a.table_schema = _schema and a.table_name= table_name
and a.column_name=self_name;
if cou=0
then leave pro_begin;
end if;
select count(1) into cou
from information_schema.columns a where a.table_schema = _schema and a.table_name= table_name
and a.column_name=parent_name;
if cou=0
then leave pro_begin;
end if;
set tree_sql1= concat('select count(1) into @l_value from ',table_name,' t where t.',self_name,' = ',self_value);
select tree_sql1;
set @tree_sql1=tree_sql1; ##注意很重要,将连成成的字符串赋值给一个变量(可以之前没有定义,但要以@开头)
prepare stmt from @tree_sql1; ##预处理需要执行的动态SQL,其中stmt是一个变量
EXECUTE stmt; ##执行SQL语句
deallocate prepare stmt; ##释放掉预处理段
set cou=@l_value;
select cou;
if cou=0
then leave pro_begin;
end if;
#type =1
#table_name的self_name值为self_value,返回parent_name的上级的上级的上级....(用分号隔开)
if type =1 then
ontTypeLoop:loop
set tree_sql1= concat('select ',parent_name,' into @l_value ',/*,id_name,' into @l_id','*/'from ',table_name,' t where t.',self_name,' = ',self_value);
#select tree_sql1;
set @tree_sql1=tree_sql1; ##注意很重要,将连成成的字符串赋值给一个变量(可以之前没有定义,但要以@开头)
prepare stmt from @tree_sql1; ##预处理需要执行的动态SQL,其中stmt是一个变量
EXECUTE stmt; ##执行SQL语句
deallocate prepare stmt; ##释放掉预处理段
if length(rt_value)=0 or rt_value is null
then
set rt_value=concat(@l_value);
else
set rt_value=concat(rt_value,';',@l_value);
end if;
set self_value=@l_value;
set tree_sql1= concat('select count(1) into @l_value from ',table_name,' t where t.',self_name,' = ',self_value);
set @tree_sql1=tree_sql1;
prepare stmt from @tree_sql1;
EXECUTE stmt;
deallocate prepare stmt;
set cou=@l_value;
if cou=0
then leave ontTypeLoop;
end if;
end loop;
end if;
#type =2
#树的子节点查询:根节点值:self_value,上级节点名:parent_name,节点id名:id_name
#利用递归返回table_name的parent_name值为self_value的下级的下级的下级....
if type=2 then
select 1;
call pro_find_tree_recursion(table_name,parent_name,id_name,self_value,rt_value);
end if;
leave pro_begin;
END