miaowenling 2011-12-08
-- 创建测试数据 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);