2012-08-31 39 views
1

我正在將存儲過程從MS-SQL轉換爲MySQL。它基於Directed Acyclic Graphs。MySQL存儲過程 - 無法重新打開表(不是臨時表)

原始MS-SQL腳本清單2中下頁:http://www.codeproject.com/Articles/22824/A-Model-to-Represent-Directed-Acyclic-Graphs-DAG-o

存儲過程節省了罰款,但沒有除去數據庫的所有行。 我試過運行調試器爲MySQL,它會通過第一次,似乎更新我使用的臨時數據表,但不更新「邊」表。它也不會在最後放棄表格。

第二次運行,如果我手動刪除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 ; 

我仔細檢查過我的語法,但我認爲有一個錯誤在那裏的某個地方。任何幫助不勝感激。

回答

2

有可能是一個更簡潔的方法,但我認爲你需要創建一個填充

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; 
+0

Joocer - 你是明星。一旦我將它正確地複製出來,就可以完美工作:) –

+0

只需要注意,在我的Mysql 5.5.31版本上,我可以使用查詢,而不需要innerPurgeListTable – trs79

相關問題