【问题标题】:MySQL Stored Procedure - Can't reopen table (not a temporary table)MySQL 存储过程 - 无法重新打开表(不是临时表)
【发布时间】:2012-08-31 10:17:47
【问题描述】:

我正在将存储过程从 MS-SQL 转换为 MySQL。它基于有向无环图。

原始 MS-SQL 脚本在下一页的清单 2 中:http://www.codeproject.com/Articles/22824/A-Model-to-Represent-Directed-Acyclic-Graphs-DAG-o

存储过程保存得很好,但没有从数据库中删除任何行。 我尝试通过 Debugger for MySQL 运行,它会第一次通过并且似乎更新了我用于临时数据的表,但不更新“edges”表。它也不会在最后删除表格。

第二次运行,如果我手动删除 purgelist 表,它将运行到 REPEAT 语句,然后我得到错误代码:1137 SQLState:HY000,消息:无法重新打开表:'purgelist'。 最初我想使用临时表,但我知道我不能像 SELECT 那样多次引用临时表,但是,我很惊讶这个错误发生在非临时表上。此外,我认识到在多会话环境中,我需要动态命名 purgelist。

这里是 MySQL 代码:

DELIMITER //
CREATE PROCEDURE RemoveEdge(
IN iId int(11)
)

MAIN_BLOCK: BEGIN

DECLARE counter int default 0;
DECLARE rcount int default 0;
SET counter = ( SELECT id FROM edges WHERE id = iId AND hops = 0 );
IF counter = 0 THEN
   BEGIN
      LEAVE MAIN_BLOCK;
   END;
END IF;

CREATE TABLE purgeList (id int);

-- step 1: rows that were originally inserted with the first
-- AddEdge call for this direct edge
INSERT INTO purgeList
    SELECT id
      FROM edges
      WHERE directEdgeId = iId;

-- step 2: scan and find all dependent rows that are inserted afterwards
REPEAT
    INSERT INTO purgeList
        SELECT id    
            FROM edges
            WHERE hops > 0
                AND ( entryEdgeId IN ( SELECT id FROM purgeList ) 
                    OR exitEdgeId IN ( SELECT id FROM purgeList ) )
            AND id NOT IN (SELECT id FROM purgeList );
    SET rcount = ROW_COUNT();
UNTIL rcount = 0
END REPEAT;

DELETE FROM edges
   WHERE id IN ( SELECT id FROM purgeList);
DROP TABLE purgeList;
END //
DELIMITER ;

我已经仔细检查了我的语法,但我认为某处存在错误。非常感谢任何帮助。

【问题讨论】:

    标签: mysql stored-procedures


    【解决方案1】:

    可能有一种更简洁的方法,但我认为您需要在重复中创建一个临时表,其中填充有

    SELECT id FROM purgeList
    

    然后引用临时表而不是 purgeList,如下所示:

    REPEAT
    
        CREATE TABLE innerPurgeList (id int);
    
        INSERT INTO innerPurgeList
           SELECT id
                FROM purgeList;
    
        INSERT INTO purgeList
           SELECT id    
                FROM edges
                WHERE hops > 0
                    AND ( entryEdgeId IN ( innerPurgeList ) 
                        OR exitEdgeId IN ( innerPurgeList ) )
                AND id NOT IN ( innerPurgeList );
        SET rcount = ROW_COUNT();
    
        DROP TABLE innerPurgeList;
    
    UNTIL rcount = 0
    END REPEAT;
    

    【讨论】:

    • Joocer - 你是明星。一旦我正确复制它,就可以完美地工作:)
    • 请注意,在我的 Mysql 5.5.31 版本上,我可以使用编写的查询,而不需要 innerPurgeListTable
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-05-19
    • 2012-11-19
    • 1970-01-01
    • 2010-09-25
    • 2011-07-15
    • 1970-01-01
    • 2021-12-24
    相关资源
    最近更新 更多