我有用户表,其中包含以下字段
用户
user_id INT
parent_user_id INT
一个INT
b INT
我想创建一个返回给定parent_user_id
的所有子节点的过程这里有我的
DROP PROCEDURE IF EXISTS read_user_tree;
DELIMITER //
CREATE PROCEDURE read_user_tree(IN input_data INT) NOT DETERMINISTIC
BEGIN
SET @id = input_data;
myLoop: loop
SELECT `user_id`, `a`, `b` into @id, @a, @b FROM `user` WHERE parent_user_id = @id;
if
@id is null
then
leave myLoop;
end if;
SELECT `user_id`, `a`, `b` FROM `user` WHERE user_id = @a
union
SELECT `user_id`, `a`, `b` FROM `user` WHERE user_id = @b;
end loop myLoop;
END //
DELIMITER ;
当我运行此PROCEDURE时,我得到的是随机结果而不是树数据
编辑1:
我尝试将数据添加到临时表中但收到错误“#1172 - 结果由多行组成”
DROP PROCEDURE IF EXISTS read_user_tree;
DELIMITER //
CREATE PROCEDURE read_user_tree(IN input_data INT) NOT DETERMINISTIC
BEGIN
SET @id = input_data;
CREATE TEMPORARY TABLE tmp_user_data (
`user_id` int(11) NOT NULL,
`a` int(11) NOT NULL,
`b` int(11) NOT NULL,
`parent_user_id` int(11) NOT NULL
) ENGINE=MEMORY DEFAULT CHARSET=latin1;
myLoop: loop
SELECT `user_id`, `a`, `b` into @id, @a, @b FROM `user` WHERE parent_user_id = @id;
if
@id is null
then
leave myLoop;
end if;
insert into tmp_user_data (`user_id`, `a`, `b`, `parent_user_id`)
SELECT `user_id`, `a`, `b`, `parent_user_id` FROM `user` WHERE user_id = @a;
insert into tmp_user_data (`user_id`, `a`, `b`, `parent_user_id`)
SELECT `user_id`, `a`, `b`, `parent_user_id` FROM `user` WHERE user_id = @b;
end loop myLoop;
select * from tmp_user_data;
END //
DELIMITER ;
编辑2:
在添加第二个tmp表以用作队列后,我得到了期望结果
DROP PROCEDURE IF EXISTS read_user_tree;
DELIMITER //
CREATE PROCEDURE read_user_tree(IN input_data INT) NOT DETERMINISTIC
BEGIN
SET @id = input_data;
CREATE TEMPORARY TABLE tmp_user_data (
`user_id` int(11) NOT NULL,
`a` int(11) ,
`b` int(11) ,
`parent_user_id` int(11)
) ENGINE=MEMORY DEFAULT CHARSET=latin1;
CREATE TEMPORARY TABLE tmp_user_level (
`user_id` int(11) NOT NULL
) ENGINE=MEMORY DEFAULT CHARSET=latin1;
insert into tmp_user_level select user_id from `user` WHERE parent_user_id = @id;
myLoop: loop
select user_id into @cur from tmp_user_level LIMIT 1;
select FOUND_ROWS() into @cnt;
if
@cnt = 0
then
leave myLoop;
end if;
SELECT `user_id`, `a`, `b`, `parent_user_id` into @user_id, @a, @b, @parent_user_id FROM `user` WHERE user_id = @cur;
insert into tmp_user_data (`user_id`, `a`, `b`, `parent_user_id`) values( @user_id, @a, @b, @parent_user_id);
delete from tmp_user_level where user_id = @cur;
if
@a is not null
then
insert into tmp_user_level (user_id) values(@a);
end if;
if
@b is not null
then
insert into tmp_user_level (user_id) values(@b);
end if;
end loop myLoop;
select * from tmp_user_data;
END //
DELIMITER ;
答案 0 :(得分:0)
从记忆中走出来,如果错误就道歉。但是您可能需要创建临时表并在循环内插入查询结果。这就是我以前的做法。
CREATE TEMPORARY TABLE results LIKE `user`;
...
<loop>
...
INSERT INTO results (user, a, b)
SELECT ... UNION SELECT ... ;
...
</loop>
SELECT * FROM results;
DROP TEMPORARY TABLE results;
您必须拥有创建临时表的权限;