欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  数据库

一个递归获取祖先元素值的MySQL函数范例

程序员文章站 2022-05-07 22:13:51
...

test.sql:-- 创建测试数据 drop table if exists T1; CREATE TABLE T1 ( id bigint NOT NULL auto_increment, pid bigint,

test.sql:-- 创建测试数据
drop table if exists T1;
CREATE TABLE T1 (
id bigint NOT NULL auto_increment,
pid bigint,
code varchar(255),
PRIMARY KEY (id)
);
insert into t1(id,pid,code) values(1,null,'1');
insert into t1(id,pid,code) values(2,null,'2');
insert into t1(id,pid,code) values(3,1,'1.1');
insert into t1(id,pid,code) values(4,1,'1.2');
insert into t1(id,pid,code) values(5,2,'2.1');
insert into t1(id,pid,code) values(6,3,'1.1.1');
select * from t1 order by code;

-- 定义递归处理函数:获取祖先的id和code,并用符号'/'按序连接,id和code间用';'连接
DELIMITER $$
DROP FUNCTION IF EXISTS getAncestors $$
CREATE FUNCTION getAncestors(id bigint) RETURNS VARCHAR(1000)
BEGIN
DECLARE done INT DEFAULT 0;
DECLARE r VARCHAR(1000);
DECLARE ri VARCHAR(1000);
DECLARE rc VARCHAR(1000);
DECLARE lev int;
DECLARE cid bigint;
DECLARE pid bigint;
DECLARE pcode VARCHAR(255);
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;

SET cid = id;
SET lev = 0;
SET ri = '';
SET rc = '';
REPEAT
SELECT p.id,p.code into pid,pcode FROM T1 c inner join T1 p on p.id=c.pid where c.id=cid;
IF NOT done THEN
SET cid = pid;
if length(ri) > 0 then
SET ri = concat(cast(pid as char),'/',ri);
SET rc = concat(cast(pid as char),'/',rc);
else
SET ri= cast(pid as char);
SET rc= pcode;
end if;
END IF;
UNTIL done END REPEAT;
if length(ri) > 0 then
SET r = concat(ri,';',rc);
else
SET r = null;
end if;
RETURN r;
END $$
DELIMITER ;
-- 返回:null;
select getAncestors(1);
-- 返回:'1;1';
select getAncestors(3);
-- 返回:'1/3;1/1.1';
select getAncestors(6);

一个递归获取祖先元素值的MySQL函数范例