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


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);

相关内容