mysql存储过程-递归赋值国家地区

申明:下列存储过程适合表已经有数据,需要为某字段赋值(国,省,市,区,县等)数据时使用。

1.创建regionAdd存储过程,查询国表信息传入参数到reg存储过程中
/*删除存储过程regionAdd*/
DROP PROCEDURE regionAdd;
/*创建存储过程regionAdd*/
create PROCEDURE regionAdd()
/*开始存储过程*/
BEGIN
    DECLARE id int;    /*接收国id*/
    DECLARE full_id VARCHAR(100); /*接收国id*/
    declare full_name VARCHAR(100);/*接收国名*/
    DECLARE b int default 0;/*定义异常参数*/
    /*创建游标接收查询的country表的列值*/
    DECLARE pid CURSOR for select c.id,c.id,c.zh_name from country c;
    /*定义异常,游标的数据为空时异常,异常参数修改为b 修改为1*/
    DECLARE CONTINUE HANDLER for not FOUND set b = 1;
    /*打开游标*/
    OPEN pid;
    /*读取第一行数据存储到pid中*/
    FETCH pid into id,full_id,full_name;
    /*开始循环,数据不为空的时候循环(b=1时游标数据为空)*/
    WHILE b <> 1 DO
    /*调用reg存储过程,传入,国id,国id,国名,国id*/
            call reg(id,full_id,full_name,id);
    /*读取下一条信息*/
            FETCH pid into id,full_id,full_name;
    /*结束循环*/
    end while;
    /*关闭游标*/
    CLOSE pid;
    /*结束存储过程*/
END;



/*删除reg存储过程*/
DROP PROCEDURE reg;
/*创建reg存储过程,参数为,地区父id,地区父id全(1,11,112),地区父name全(中国,北京市,朝阳区),国id*/
create PROCEDURE reg(IN pid int,in fullId VARCHAR(100),in fullName VARCHAR(100),in countryId int)
/*开始存储过程*/
BEGIN

        declare  dids int;/*接收当前地区id*/
        declare  rnames VARCHAR(100);/*接收当前地区名*/
        declare  fullids VARCHAR(100);/*存储当前id全(1,11,112)*/
        declare  fullnames VARCHAR(100);/*存储当前地区名全(中国,北京市,朝阳区)*/
        declare  b int default 0; /*定义异常参数*/
        /*定义游标regionup,查询地区,id,区名,id全,取名全*/
        DECLARE regionup CURSOR for select r.id,r.name,r.full_id,r.full_name from region r where r.parent_id = pid;
        /*定义异常,游标的数据为空时异常,异常参数修改为b 修改为1*/
        DECLARE CONTINUE HANDLER for not FOUND set b = 1;
        /*开始游标*/
        OPEN regionup;
        /*读取游标中第一行数据*/
        FETCH regionup into dids,rnames,fullids,fullnames;
        /*开始循环,数据不为空的时候循环(b=1时游标数据为空)*/
        WHILE b <> 1 DO
            /*获取当前地区全名,父类地区全名+当前地区名*/
                set fullnames = concat(fullName,',',rnames);
            /*获取当前id全,父类id全+当前id*/
                set fullids = concat(fullId,',',dids);
            /*修改当前地区全,di全,国id*/
                update region res set  res.full_id = fullids , res.full_name = fullnames ,res.country_id = countryId  where res.id = dids;
            /*递归调用自己,传入,当前区id,当前区id全,当前国全名,国id*/
                call reg(dids,fullids,fullnames,countryId);
            /*读取下一条信息*/ 
        FETCH regionup into dids,rnames,fullids,fullnames;
        /*结束循环*/
        end while;
        /*关闭游标*/
        CLOSE regionup;
/*结束存储过程*/
end;


2.调用存储过程,调用前需要设置循环深度
/*
这个修改课涉及到全局和session级修改,全局修改的话 需要 有super权限: set global max_sp_recursion_depth=2, session级修改的话只对当前连接有效。不需要加global
你可以执行 show privileges 查看权限列表,找到super
*/
SET global  max_sp_recursion_depth=25;/*深度自定义,不定义将不能实现递归*/
call regionAdd;/*调用存储过程*/
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
MySQL 存储过程是一种在 MySQL 数据库中存储并执行 SQL 语句的方法。MySQL 存储过程可以使用递归技术来处理一些需要对同一数据进行多次处理的问题,比如树形结构的遍历、图形结构的遍历等。下面是一个使用 MySQL 存储过程实现递归的示例: 首先,我们需要创建一个表,用于存储树形结构的数据。假设这个表名为 `tree`,包含如下字段: ``` id INT PRIMARY KEY, name VARCHAR(255), parent_id INT ``` 其中,`id` 是节点的唯一标识符,`name` 是节点的名称,`parent_id` 是节点的父节点标识符。如果一个节点没有父节点,则其 `parent_id` 为 NULL。 接下来,我们可以创建一个存储过程,用于从指定的节点开始遍历整个树形结构。这个存储过程包含两个参数:起始节点的 `id` 和当前节点的深度。 ``` CREATE PROCEDURE traverse_tree (IN start_id INT, IN depth INT) BEGIN DECLARE done INT DEFAULT FALSE; DECLARE cur_id INT; DECLARE cur_depth INT; -- 创建一个游标,查询当前节点的所有子节点 DECLARE cur CURSOR FOR SELECT id FROM tree WHERE parent_id = start_id; DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE; -- 遍历所有子节点 OPEN cur; read_loop: LOOP FETCH cur INTO cur_id; IF done THEN LEAVE read_loop; END IF; -- 处理当前节点 SET cur_depth = depth + 1; SELECT CONCAT(REPEAT(' ', depth), name) FROM tree WHERE id = cur_id; -- 递归处理当前节点的子节点 CALL traverse_tree(cur_id, cur_depth); END LOOP; CLOSE cur; END; ``` 这个存储过程使用游标查询当前节点的所有子节点,并递归调用自己处理子节点。它还使用了一个 `depth` 参数,用于记录当前节点的深度,以便输出时缩进一定的空格。 我们可以调用这个存储过程,从指定的节点开始遍历树形结构。 ``` CALL traverse_tree(1, 0); ``` 其中,`1` 是起始节点的 `id`,`0` 是起始节点的深度(根节点的深度为 0)。这个存储过程将会输出整个树形结构的层次结构。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值