我已經將我的問題簡化爲這個簡單的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