如何在mysql中进行无限递归?

时间:2013-09-27 09:38:41

标签: mysql recursion

我有一个mysql存储过程递归,它总是最多返回499行。 我的存储过程是在树中移动(不是二叉树)并检查节点是否有子节点等等,直到它到达树叶。

我不知道如何将我的代码转换为非递归方式,我只想问两个要点:

  • 如何在mysql中创建无限递归(mysql服务器版本是5.5)?
  • 如果不能发生,我怎样才能将我的鳕鱼改成非递归方式?

    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
    

1 个答案:

答案 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())不会相互踩踏。