我已经将我的问题简化为这个简单的SP。列名在最后被缓存在SELECT *中。我不知道为什么或如何阻止它。我尝试添加SQL_NO_CACHE,但这没有什么区别。如预期为什么mysql缓存被删除临时表的列名?
mysql> CALL mysp(0);
+------+
| col1 |
+------+
| 1 |
| 3 |
| 5 |
+------+
3 rows in set (0.17 sec)
+----------------------------------+
| Result |
+----------------------------------+
| Please see new temp table mydata |
+----------------------------------+
1 row in set (0.17 sec)
Query OK, 0 rows affected (0.17 sec)
DROP TABLE IF EXISTS foo;
CREATE TABLE foo(
col1 int,
col2 int);
INSERT INTO foo VALUES(1,2),(3,4),(5,6);
DROP PROCEDURE IF EXISTS mysp;
DELIMITER ;;
CREATE [email protected] PROCEDURE mysp(c INT)
BEGIN
DROP TABLE IF EXISTS mydata;
SET @mycol='col1';
IF c > 0 THEN SET @mycol:='col2';
END IF;
SET @s=CONCAT('CREATE TEMPORARY TABLE mydata AS SELECT ', @mycol, ' FROM foo');
PREPARE stmt FROM @s;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
-- The following select call fails on 2nd and subsequent executions of the SP
SELECT SQL_NO_CACHE * FROM mydata;
SELECT "Please see new temp table mydata" as Result;
END ;;
DELIMITER ;
版本
mysql> SELECT VERSION();
+------------+
| VERSION() |
+------------+
| 5.5.15-log |
+------------+
1 row in set (0.00 sec)
首先运行工作正常,现在,如果我尝试运行它再次使用另一列
mysql> CALL mysp(1);
ERROR 1054 (42S22): Unknown column 'qlgqp1.mydata.col1' in 'field list'
mysql> SELECT @mycol;
+--------+
| @mycol |
+--------+
| col2 |
+--------+
1 row in set (0.00 sec)
如果我重新存储过程再次它的窝RKS
mysql> CALL mysp(1);
+------+
| col2 |
+------+
| 2 |
| 4 |
| 6 |
+------+
3 rows in set (0.18 sec)
+----------------------------------+
| Result |
+----------------------------------+
| Please see new temp table mydata |
+----------------------------------+
1 row in set (0.18 sec)
Query OK, 0 rows affected (0.18 sec)
但是,如果我试图切换回第一列 - 即使我尝试第一次投放的临时表 - 它仍然无法正常工作要求通过eggyal
mysql> CALL mysp(0);
ERROR 1054 (42S22): Unknown column 'qlgqp1.mydata.col2' in 'field list'
mysql> DROP TABLE mydata;
Query OK, 0 rows affected (0.03 sec)
mysql> CALL mysp(0);
ERROR 1054 (42S22): Unknown column 'qlgqp1.mydata.col2' in 'field list'
mysql>
* 其他信息。另外我在另一个mysql版本上尝试了这个结果。 *
mysql> CALL mysp(1);
+------+
| col2 |
+------+
| 2 |
| 4 |
| 6 |
+------+
3 rows in set (0.20 sec)
+----------------------------------+
| Result |
+----------------------------------+
| Please see new temp table mydata |
+----------------------------------+
1 row in set (0.20 sec)
Query OK, 0 rows affected (0.20 sec)
mysql> describe mydata;
+-------+---------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+---------+------+-----+---------+-------+
| col2 | int(11) | YES | | NULL | |
+-------+---------+------+-----+---------+-------+
1 row in set (0.00 sec)
mysql> CALL mysp(0);
ERROR 1054 (42S22): Unknown column 'test.mydata.col2' in 'field list'
mysql> describe mydata;
+-------+---------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+---------+------+-----+---------+-------+
| col1 | int(11) | YES | | NULL | |
+-------+---------+------+-----+---------+-------+
1 row in set (0.00 sec)
修复的有趣的发展 - 不断变化的最后几行到准备好的语句的工作 - 但正如前面使用完全相同的查询。
-- The following select call fails on 2nd and subsequent executions of the SP
PREPARE stmt FROM 'SELECT SQL_NO_CACHE * FROM mydata';
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
SELECT "Please see new temp table mydata" as Result;
这个错误真的来自那个SP吗?你可以在每次调用SP后显示“mydata”的内容吗? – eggyal 2012-07-06 22:58:10
已添加。我开始怀疑MySQL客户端缓存的东西。 – 2012-07-07 00:12:39
好的,所以'*'在执行准备好的语句之前显然会被扩展(可能是在调用SP之后)。我不认为用'MODIFIES SQL DATA'特征定义过程有什么区别?事先没有将'*'限定为'mydata。*'或调用'FLUSH TABLES mydata'?如果没有,你可以通过另一个准备好的语句(如@ spencer7593建议的)或者通过本程序调用的第二个过程执行'SELECT'。我在手册中找不到任何有关此行为的参考,因此我倾向于将其解释为一个错误。 – eggyal 2012-07-07 01:22:11