Почему mysql кэширует имена столбцов удаляемой временной таблицы?

Я сократил свою проблему до этого простого SP. Имена столбцов кэшируются в SELECT *в конце. Я понятия не имею, почему и как это остановить. Я попытался добавить SQL _NO _CACHE, но это не имеет значения.

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 DEFINER=root@localhost 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(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)

Теперь, если я попытаюсь запустить его снова, используя другой столбец

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)

Если я снова создам хранимую процедуру, она сработает

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)

Но если я попытаюсь вернуться к первому столбцу -, даже если я попытаюсь сначала удалить временную таблицу -, это все равно не сработает

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>

*Дополнительная информация, запрошенная eggyal. Также я попробовал это на другой версии 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;
0
задан Adrian Cornish 7 July 2012 в 02:02
поделиться