我有一个mysql存储过程递归,它总是最多返回499行。 我的存储过程是在树中移动(不是二叉树)并检查节点是否有子节点等等,直到它到达树叶。
我不知道如何将我的代码转换为非递归方式,我只想问两个要点:
如果不能发生,我怎样才能将我的鳕鱼改成非递归方式?
CREATE PROCEDURE `get_citations`(in _pub_id int(10),in _lvl int,citation_count int)
BEGIN
DECLARE done INT DEFAULT FALSE;
declare p_id,c_count int;
declare _counter int default 1;
DECLARE cur1 CURSOR FOR SELECT pat_publn_id,cited_count from temp.a_citations
where pub_parent=_pub_id ;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
insert into a_citations
(pat_publn_id ,
publn_nr ,
publn_kind,
publn_auth,
publn_date,
cited_pat_publn_id,
cited_count,
pub_lvl,
pub_parent)
(select p.pat_publn_id,p.publn_nr,p.publn_kind,p.publn_auth,p.publn_date,c.cited_pat_publn_id,
(select count(*) as cnt FROM patstat1304.tls212_citation c2 where c2.cited_pat_publn_id=c.pat_publn_id) as cited_count,_lvl as pub_lvl,_pub_id as pub_parent
from patstat1304.tls212_citation c,patstat1304.tls211_pat_publn p
where c.pat_publn_id=p.pat_publn_id and c.cited_pat_publn_id=_pub_id);
commit;
OPEN cur1;
read_loop: LOOP
fetch cur1 into p_id,c_count;
IF (c_count !=0) then
call get_citations( p_id,_lvl+1,c_count);
commit;
END if;
IF done THEN
LEAVE read_loop;
END IF;
set _counter=_counter+1;
if(_counter=citation_count) then
LEAVE read_loop;
end if;
end loop;
CLOSE cur1;
END
答案 0 :(得分:0)
MySQL无法使用非常深的嵌套来执行存储过程。
很快就会出现错误ER_STACK_OVERRUN_NEED_MORE
。
增加线程堆栈以进一步发挥作用也不起作用。
要将递归调用更改为非递归调用,请考虑以下内容:
1)创建一个名为publications_to_process的表,其中包含发布和搜索级别。
2)要开始搜索,请在此表中插入原始出版物,级别为1。
3)在循环中,获取一个发布,检查引用,并添加publications_to_process中列出的发布,增加级别。
4)作为奖励,适用于以下情况:
Pub_1 - > Pub_2 - > Pub_3, Pub_1 - > Pub_3
如果已经处理了Pub_3,则无需再次将其添加到搜索中。
换句话说,出版物更可能是树的有向图。
5)要么使表临时,要么考虑添加PROCESSLIST_ID
列,以便在并行执行此搜索时,不同的会话(具有不同的CONNECTION_ID()
)不会相互踩踏。