Mysql递归存储过程…达到限制0…可以';t更改max_sp_recursion_depth变量
更新:好的,我能够调试它,并且发现通过这样做Mysql递归存储过程…达到限制0…可以';t更改max_sp_recursion_depth变量,sql,mysql,stored-procedures,Sql,Mysql,Stored Procedures,更新:好的,我能够调试它,并且发现通过这样做select@@max\u sp\u recursion\u depth我可以看到变量被设置为15,但是,当我使用call single\u limb\u portfolio\u列表(xaccount\u id,xparent\u portfolio\u id)运行对自身的调用时我得到一个错误,指出已达到递归限制0,但它从未在自身上迭代过一次' 当我运行下面的递归存储过程时,我不断得到“递归限制0已超出”,即使我将其设置为set max\u sp\u
select@@max\u sp\u recursion\u depth
我可以看到变量被设置为15,但是,当我使用call single\u limb\u portfolio\u列表(xaccount\u id,xparent\u portfolio\u id)运行对自身的调用时代码>我得到一个错误,指出已达到递归限制0,但它从未在自身上迭代过一次'
当我运行下面的递归存储过程时,我不断得到“递归限制0已超出”,即使我将其设置为set max\u sp\u recursion\u depth=15代码>
我是否将此变量设置在错误的位置?它表现得好像永远不会被设定,总是保持在零
提前感谢你的帮助
递归存储过程:
CREATE DEFINER=`aaron`@`localhost` PROCEDURE `single_limb_portfolio_list`(xaccount_id INT, IN portf_id_in INT, OUT str_portf_list VARCHAR(455))
BEGIN
DECLARE xportfolio_ID INT DEFAULT NULL ;
DECLARE xp_name INT DEFAULT NULL ;
DECLARE xparent_portfolio_id INT DEFAULT NULL ;
DECLARE xstr_list VARCHAR(455) ;
SET max_sp_recursion_depth = 15 ;
SELECT portfolio_id, p_name, parent_portfolio_id
FROM portfolio
WHERE account_id = xaccount_id
AND archived = 0
AND portfolio_id = portf_id_in
INTO xportfolio_ID, xp_name, xparent_portfolio_id;
IF xportfolio_ID IS NULL /* We have reached the top of the tree and there are no more parents for the portfolio list */
THEN
SET str_portf_list = xstr_list; #Set the full tree list to the variable that will be inserted as a row into the temp table previously created
ELSE
CALL single_limb_portfolio_list(xaccount_id, xparent_portfolio_id); #call the sproc with the next portfolio id to get the next parent id
SET xstr_list = concat(xp_name,"->",xstr_list); #Add the portfolio name to the overall portfolio list. Output like: "California -> Los Angelas"
END IF;
END
这是一个非递归的解决方案,您可以根据您的模型进行调整(http://pastie.org/1259300)
我会点头的…谢谢你的回复。我做了类似的事情,但不是在存储过程中。我已经编写了一个php函数来遍历树并给出我想要的,我意识到我可以简单地运行该函数,然后将我想要的树结构插入表中。
drop table if exists product;
create table product
(
prod_id smallint unsigned not null auto_increment primary key,
name varchar(255) not null,
parent_id smallint unsigned null,
key (parent_id)
)engine = innodb;
insert into product (name, parent_id) values
('Products',null),
('Systems & Bundles',1),
('Components',1),
('Processors',3),
('Motherboards',3),
('AMD',5),
('Intel',5),
('Intel LGA1366',7);
delimiter ;
drop procedure if exists product_hier;
delimiter #
create procedure product_hier
(
in p_prod_id smallint unsigned
)
begin
declare v_done tinyint unsigned default 0;
declare v_depth smallint unsigned default 0;
create temporary table hier(
parent_id smallint unsigned,
prod_id smallint unsigned,
depth smallint unsigned default 0
)engine = memory;
insert into hier select parent_id, prod_id, v_depth from product where prod_id = p_prod_id;
/* http://dev.mysql.com/doc/refman/5.0/en/temporary-table-problems.html */
create temporary table tmp engine=memory select * from hier;
while not v_done do
if exists( select 1 from product p inner join hier on p.parent_id = hier.prod_id and hier.depth = v_depth) then
insert into hier
select p.parent_id, p.prod_id, v_depth + 1 from product p
inner join tmp on p.parent_id = tmp.prod_id and tmp.depth = v_depth;
set v_depth = v_depth + 1;
truncate table tmp;
insert into tmp select * from hier where depth = v_depth;
else
set v_done = 1;
end if;
end while;
select
p.prod_id,
p.name as prod_name,
b.prod_id as parent_prod_id,
b.name as parent_prod_name,
hier.depth
from
hier
inner join product p on hier.prod_id = p.prod_id
inner join product b on hier.parent_id = b.prod_id
order by
hier.depth, hier.prod_id;
drop temporary table if exists hier;
drop temporary table if exists tmp;
end #
delimiter ;
call product_hier(3);
call product_hier(5);