2016-09-29 87 views
0

這裏是'backstory':我有一個mysql存儲過程,最終創建表,然後它應該在proc結束時銷燬表。我這樣做的原因是因爲我想確保如果proc失敗,我不會最終堆疊我創建的這些「臨時」表(他們確實不是臨時表,但我只是打電話他們,因爲他們應該被刪除,當我完成了過程)。無論如何,我的proc的前20行是在下面。mysql stored proc truncate table

-- build dynamic sql to drop any tables that have been around for longer than 30 seconds 

SELECT CONCAT('DROP TABLE IF EXISTS ',GROUP_CONCAT(TableName),';') 
INTO @dropcmd FROM TempTableTracker WHERE TIMESTAMPDIFF(SECOND, Created, NOW()) > 30; 

-- execute dynamic sql 
PREPARE dropcmd FROM @dropcmd; 
EXECUTE dropcmd; 
DEALLOCATE PREPARE dropcmd; 

DELETE FROM TempTableTracker WHERE TIMESTAMPDIFF(SECOND, Created, NOW()) > 30; 

SET @nextOutTable = concat('Insert into TempTableTracker (Created, TableName) values (NOW(),''',tableName,''')'); 
PREPARE nextOutTable FROM @nextOutTable; 
EXECUTE nextOutTable; 
DEALLOCATE PREPARE nextOutTable; 

我們把proc目前扔,說 錯誤「不是唯一的表/別名:‘HelperTable088747200147510875390’」 如果我註釋掉下面這段代碼,然後將PROC工作

PREPARE dropcmd FROM @dropcmd; 
EXECUTE dropcmd; 
DEALLOCATE PREPARE dropcmd; 

對我來說真的沒什麼意義。如果我運行了我從sql編輯器中手動註釋掉的代碼(加上select concat語句...不在proc中),那麼它也可以工作。有關可能會發生什麼的任何想法?

這裏是整個PROC - >

DELIMITER ;; 
CREATE PROCEDURE "usergroupCalcs"(IN sqlstatement TEXT, IN tableName  VARCHAR(1000), IN topLevelParentID INT) 
BEGIN 

-- build dynamic sql (DROP TABLE tbl1, tbl2...;) 
SELECT CONCAT('DROP TABLE IF EXISTS ',GROUP_CONCAT(TableName),';') 
INTO @dropcmd FROM TempTableTracker WHERE TIMESTAMPDIFF(SECOND, Created, NOW()) > 30; 

-- execute dynamic sql 
PREPARE dropcmd FROM @dropcmd; 
EXECUTE dropcmd; 
DEALLOCATE PREPARE dropcmd; 

DELETE FROM TempTableTracker WHERE TIMESTAMPDIFF(SECOND, Created, NOW()) > 30; 

SET @nextOutTable = concat('Insert into TempTableTracker (Created, TableName)  values (NOW(),''',tableName,''')'); 
PREPARE nextOutTable FROM @nextOutTable; 
EXECUTE nextOutTable; 
DEALLOCATE PREPARE nextOutTable; 



SET @dropTable = concat('Drop table if exists ',tableName); 
PREPARE dropTable FROM @dropTable; 
EXECUTE dropTable; 
DEALLOCATE PREPARE dropTable; 



SET @createTable = concat('CREATE TABLE ',tableName,' (usergroupID INT, storeID INT, parentID INT, INDEX ug (`usergroupID`), INDEX st (`storeID`), INDEX pim (`parentID`)) ENGINE=MEMORY'); 
PREPARE createTable FROM @createTable; 
EXECUTE createTable; 
DEALLOCATE PREPARE createTable; 




SET @insertIntoTable = concat('INSERT INTO ',tableName, ' ',sqlstatement); 
PREPARE insertIntoTable FROM @insertIntoTable; 
EXECUTE insertIntoTable; 
DEALLOCATE PREPARE insertIntoTable; 


SET @repeatStatement = concat('DELETE entry.* FROM ',tableName,' entry LEFT JOIN ',tableName,' parent ON entry.parentID = parent.usergroupID AND entry.storeID = parent.storeID WHERE parent.usergroupID IS NULL AND entry.parentID NOT IN (',topLevelParentID,')'); 
PREPARE repeatStatement FROM @repeatStatement; 

    REPEAT 
    EXECUTE repeatStatement; 
    UNTIL row_count() = 0 END REPEAT; 

    DEALLOCATE PREPARE repeatStatement; 

SET @dropTempTable = concat('DROP TEMPORARY TABLE IF EXISTS ',tableName,'_out'); 
PREPARE dropTempTable FROM @dropTempTable; 
EXECUTE dropTempTable; 
DEALLOCATE PREPARE dropTempTable; 


SET @createTempTable = concat('CREATE TEMPORARY TABLE ',tableName,'_out (usergroupID INT, storeID INT, parentID INT, INDEX ug (`usergroupID`), INDEX st (`storeID`), INDEX pim (`parentID`)) ENGINE=MEMORY COLLATE ''utf8_general_ci'' as select * from ',tableName); 
PREPARE createTempTable FROM @createTempTable; 
EXECUTE createTempTable; 
DEALLOCATE PREPARE createTempTable; 


SET @dropTempTableTwo = concat('DROP TABLE IF EXISTS ',tableName); 
PREPARE dropTempTableTwo FROM @dropTempTableTwo; 
EXECUTE dropTempTableTwo; 
DEALLOCATE PREPARE dropTempTableTwo; 


END;; 
DELIMITER ; 
+0

你爲什麼不使用'CREATE TEMPORARY TABLE'。當你關閉數據庫連接時,它們會自動被刪除。 – Barmar

+0

DROP TABLE IF EXISTS'爲任何不存在的表生成警告。這聽起來像是把警告轉化爲錯誤。 – Barmar

+0

顯示如何調用存儲過程並顯示create proc行。當然,你將rem的東西做得很好,因爲那是執行字符串的部分。如果您希望我知道您希望我解決問題,請執行「hey @drew there is the edit」...做一個[編輯] – Drew

回答

0

我想通了..蠢蠢。我有一個名爲tableName的var,我也在delete語句中引用了一個名爲TableName的列。它將group_concat語句中列的表名var代入,這就是它失敗的原因。