您的位置:首页 > 其它

取出所有树形结构父节点下的子节点(用存储过程实现)

2015-05-06 17:50 661 查看
分析:常规的话,都会想到用递归去实现,可是递归只能调用自身100次,很容易就提示错误了。所以这里采用存储过程的方式,将父节点下的所有子节点取出

简单示例:

表结构:

/*
Navicat MySQL Data Transfer

Source Server         : localhost
Source Server Version : 50520
Source Host           : localhost:3306
Source Database       : test

Target Server Type    : MYSQL
Target Server Version : 50520
File Encoding         : 65001

Date: 2015-05-06 17:32:27
*/

SET FOREIGN_KEY_CHECKS=0;

-- ----------------------------
-- Table structure for user_table
-- ----------------------------
DROP TABLE IF EXISTS `user_table`;
CREATE TABLE `user_table` (
`user_id` varchar(30) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL,
`team_id` varchar(30) CHARACTER SET utf32 COLLATE utf32_unicode_ci NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

-- ----------------------------
-- Records of user_table
-- ----------------------------
INSERT INTO `user_table` VALUES ('admin', 'NULL');
INSERT INTO `user_table` VALUES ('ramu', 'admin');
INSERT INTO `user_table` VALUES ('suresh', 'admin');
INSERT INTO `user_table` VALUES ('kumar', 'ramu');
INSERT INTO `user_table` VALUES ('mahesh', 'ramu');
INSERT INTO `user_table` VALUES ('randiv', 'suresh');


存储过程代码:

CREATE DEFINER=`root`@`localhost` PROCEDURE `user_hier`(in team_id varchar(50))
BEGIN
declare count int;
declare tmp_team_id varchar(50);#声明变量
drop temporary table if exists res_hier;
drop temporary table if exists tmp_hier;
CREATE TEMPORARY TABLE res_hier(user_id varchar(50),team_id varchar(50))engine=memory;#创建临时内存表
CREATE TEMPORARY TABLE tmp_hier(user_id varchar(50),team_id varchar(50))engine=memory;
set tmp_team_id = team_id;#为变量赋值
SELECT COUNT(*) INTO count FROM user_table WHERE user_table.team_id=tmp_team_id;
WHILE count>0 DO
insert into res_hier select user_table.user_id,user_table.team_id from user_table where user_table.team_id=tmp_team_id;
insert into tmp_hier select user_table.user_id,user_table.team_id from user_table where user_table.team_id=tmp_team_id;
select user_id into tmp_team_id from tmp_hier limit 0,1;#查询内存临时表中的user_id赋给tmp_team_id,用于下次循环取对应的数据
select count(*) into count from tmp_hier;#赋给临时count
delete from tmp_hier where user_id=tmp_team_id;#删掉临时表中的user_id
end while;
select * from res_hier;
drop temporary table if exists res_hier;
drop temporary table if exists tmp_hier;
end
简单叙述上述代码功能:

1.首先创建了定义了变量count  --数量   tmp_team_id  临时变量

2.创建了两张临时内存表,调用完即回收

3.将参数中的变量赋给临时变量

4.开始循环

               这里比较难理解点:过程是根据tmp_team_id查询表中数据,然后分别插入到res_hier(要返回的结果表)和临时表tmp_hier;查询内存临时表中的user_id赋给tmp_team_id,用于下次循环取对应的数据;赋给临时count;据当前用于循环的临时变量删掉临时表中的user_id;如此反复,直到临时表中没有数据则退出循环,并返回最终结果表中的数据

实际工作中的存储过程使用:

目的:下面的存储过程是为了实现查询父节点下的所有子节点,并且把子节点的渠道id更新为参数中的渠道id

表结构如下:

CREATE TABLE `cms_member_relation` (
`rid` int(10) unsigned NOT NULL AUTO_INCREMENT,
`store_id` int(10) unsigned NOT NULL DEFAULT '0',
`channel_uid` int(10) unsigned NOT NULL DEFAULT '0',
`parent_uid` int(10) unsigned NOT NULL DEFAULT '0',
`share_uid` int(10) unsigned NOT NULL DEFAULT '0',
`uid` int(10) unsigned NOT NULL DEFAULT '0',
`addtime` int(10) unsigned NOT NULL DEFAULT '0',
`url` varchar(128) DEFAULT NULL,
`level` tinyint(3) unsigned NOT NULL DEFAULT '1',
`uid_ex` int(10) DEFAULT NULL,
`puid_ex` int(10) DEFAULT NULL,
PRIMARY KEY (`rid`),
KEY `index_member_relation` (`uid`,`parent_uid`,`channel_uid`)
) ENGINE=InnoDB AUTO_INCREMENT=22522 DEFAULT CHARSET=utf8;
测试数据sql:
-- ----------------------------
-- Records of cms_member_relation
-- ----------------------------
INSERT INTO `cms_member_relation` VALUES ('89', '175', '351', '0', '0', '451', '0', null, '1', '451', null);
INSERT INTO `cms_member_relation` VALUES ('90', '177', '351', '0', '0', '351', '0', null, '1', '453', null);
INSERT INTO `cms_member_relation` VALUES ('95', '177', '22', '351', '0', '459', '0', null, '1', '459', '456');
INSERT INTO `cms_member_relation` VALUES ('96', '175', '0', '0', '0', '460', '0', null, '1', '460', null);
INSERT INTO `cms_member_relation` VALUES ('97', '177', '22', '351', '0', '461', '0', null, '1', '461', null);
INSERT INTO `cms_member_relation` VALUES ('98', '177', '22', '461', '0', '462', '0', null, '1', '462', '453');
INSERT INTO `cms_member_relation` VALUES ('99', '177', '22', '461', '0', '463', '0', null, '1', '463', '453');
INSERT INTO `cms_member_relation` VALUES ('100', '177', '22', '462', '0', '464', '0', null, '1', '464', '462');
INSERT INTO `cms_member_relation` VALUES ('101', '177', '22', '459', '0', '577', '0', null, '1', '577', '453');
INSERT INTO `cms_member_relation` VALUES ('165', '177', '22', '459', '0', '578', '0', null, '1', '578', null);
INSERT INTO `cms_member_relation` VALUES ('166', '177', '0', '453', '0', '579', '0', null, '1', '579', '453');
INSERT INTO `cms_member_relation` VALUES ('167', '177', '0', '0', '0', '580', '0', null, '1', '580', null);
INSERT INTO `cms_member_relation` VALUES ('168', '177', '0', '456', '0', '581', '0', null, '1', '581', '456');
INSERT INTO `cms_member_relation` VALUES ('169', '177', '0', '453', '0', '582', '0', null, '1', '582', '453');
INSERT INTO `cms_member_relation` VALUES ('171', '177', '0', '456', '0', '584', '0', null, '1', '584', '456');
INSERT INTO `cms_member_relation` VALUES ('172', '177', '0', '453', '0', '585', '0', null, '1', '585', '453');
INSERT INTO `cms_member_relation` VALUES ('173', '175', '0', '0', '0', '586', '0', null, '1', '586', null);
INSERT INTO `cms_member_relation` VALUES ('174', '175', '0', '0', '0', '587', '0', null, '1', '587', null);
INSERT INTO `cms_member_relation` VALUES ('175', '177', '0', '456', '0', '588', '0', null, '1', '588', '456');
INSERT INTO `cms_member_relation` VALUES ('176', '175', '0', '0', '0', '583', '0', null, '1', '583', null);
INSERT INTO `cms_member_relation` VALUES ('177', '175', '0', '0', '0', '527', '0', null, '1', '527', null);
INSERT INTO `cms_member_relation` VALUES ('178', '177', '0', '0', '0', '521', '0', null, '1', '521', null);
INSERT INTO `cms_member_relation` VALUES ('179', '177', '0', '0', '0', '371', '0', null, '1', '371', null);
INSERT INTO `cms_member_relation` VALUES ('180', '177', '0', '457', '0', '367', '0', null, '1', '367', '457');
INSERT INTO `cms_member_relation` VALUES ('181', '177', '0', '456', '0', '368', '0', null, '1', '368', '456');
INSERT INTO `cms_member_relation` VALUES ('182', '177', '0', '456', '0', '373', '0', null, '1', '373', '456');
INSERT INTO `cms_member_relation` VALUES ('183', '177', '0', '453', '0', '374', '0', null, '1', '374', '453');
INSERT INTO `cms_member_relation` VALUES ('184', '177', '0', '453', '0', '375', '0', null, '1', '375', '453');


存储过程代码如下:

CREATE DEFINER=`root`@`localhost` PROCEDURE `member_tree`(in parent_uid int,in channel_uid int)
BEGIN
declare count int;
declare tmp_parent_uid INT;#声明变量
DECLARE tmp_result VARCHAR(30);
DECLARE tmp_channel_uid INT;
drop temporary table if exists res_member_relation;
drop temporary table if exists tmp_member_relation;
CREATE TEMPORARY TABLE res_member_relation(uid INT,parent_uid INT,channel_uid INT,UNIQUE KEY `uid` (`uid`),KEY `parent_uid` (`parent_uid`))engine=HEAP;#创建临时内存表
CREATE TEMPORARY TABLE tmp_member_relation(uid INT,parent_uid INT,channel_uid INT,UNIQUE KEY `uid` (`uid`),KEY `parent_uid` (`parent_uid`))engine=HEAP;
set tmp_parent_uid = parent_uid;#为变量赋值
set tmp_channel_uid = channel_uid;

SELECT COUNT(*) INTO count FROM cms_member_relation WHERE cms_member_relation.parent_uid=tmp_parent_uid;
loop_label:LOOP
IF count>0 THEN
select count(*) INTO tmp_result from cms_member_relation where cms_member_relation.parent_uid=tmp_parent_uid ;
IF tmp_result is NULL THEN
iterate loop_label;
ELSE
UPDATE cms_member_relation SET cms_member_relation.channel_uid=tmp_channel_uid WHERE cms_member_relation.parent_uid=tmp_parent_uid;
END IF;
insert into res_member_relation select cms_member_relation.uid,cms_member_relation.parent_uid,cms_member_relation.channel_uid from cms_member_relation where cms_member_relation.parent_uid=tmp_parent_uid ;

insert into tmp_member_relation select cms_member_relation.uid,cms_member_relation.parent_uid,cms_member_relation.channel_uid from cms_member_relation where cms_member_relation.parent_uid=tmp_parent_uid ;
select uid into tmp_parent_uid from tmp_member_relation  limit 0,1;#查询内存临时表中的uid赋给tmp_parent_uid,用于下次循环取对应的数据
select count(*) into count from tmp_member_relation;#赋给临时count
delete from tmp_member_relation where uid=tmp_parent_uid;#删掉临时表中的uid
ELSE
leave loop_label;
END if;
END LOOP;
select * from res_member_relation;
drop temporary table if exists res_member_relation;
drop temporary table if exists tmp_member_relation;
end
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐