这是'backstory':我有一个mysql存储过程,最终创建表,然后它应该在proc结束时销毁表。我这样做的原因是因为我想确保如果proc失败,我最终不会堆积我正在创建的这些“临时”表(它们实际上不是临时表但我只是调用他们,因为他们应该被删除,当我在proc中完成时)。无论如何,我的proc的前20行左右在下面。
-- 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中)那么它也可以运行。关于这里可能会发生什么的任何想法?
这是整个过程 - >
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 :(得分:0)
我想通了..愚蠢的愚蠢。我有一个名为tableName的var,我还在delete语句中引用了一个名为TableName的列。它将groupname var中传入的组替换为group_concat语句中的列,这就是它失败的原因。