MySQL 5.2,CentOS 6.4。
MySQL SELECT *在第一次传递后使用动态列和表名称由PREPARE创建的临时表失败,此时列名和表名从第一次传递更改为不同的值。
解决方法是使用从传递到传递保持相同的列别名。
DROP PROCEDURE IF EXISTS test1;
DELIMITER $$
CREATE PROCEDURE test1( column_name VARCHAR(20), table_name VARCHAR(20) )
BEGIN
SET @prepared_stmt_arg = 'prepared_stmt_arg_value';
DROP TABLE IF EXISTS tmp1;
CREATE TEMPORARY TABLE tmp1
SELECT 1 AS col_tmp1;
DROP TABLE IF EXISTS tmp2;
CREATE TEMPORARY TABLE tmp2
SELECT 2 AS col_tmp2;
# drop tmp table if it exists
DROP TABLE IF EXISTS tmp_test1;
# prepared statement
SET @prepared_stmt =
CONCAT("
CREATE TEMPORARY TABLE tmp_test1
SELECT ? AS prepared_stmt_arg, ", column_name, " # AS constant_col_alias
FROM ", table_name, "
"); # END statement
# display prepared statement before executing it
SELECT @prepared_stmt;
# prepare the statement
PREPARE ps FROM @prepared_stmt;
# execute
EXECUTE ps USING @prepared_stmt_arg;
# deallocate
DEALLOCATE PREPARE ps;
# display
SELECT * FROM tmp_test1;
END $$
DELIMITER ;
程序最后的SELECT语句失败。 (您可能需要向下滚动才能看到错误消息。)
mysql> CALL test1('col_tmp1', 'tmp1');
+---------------------------------------------------------------------------------------------------------------------------------+
| @prepared_stmt |
+---------------------------------------------------------------------------------------------------------------------------------+
|
CREATE TEMPORARY TABLE tmp_test1
SELECT ? AS prepared_stmt_arg, col_tmp1 # AS constant_col_alias
FROM tmp1
|
+---------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
+-------------------------+----------+
| prepared_stmt_arg | col_tmp1 |
+-------------------------+----------+
| prepared_stmt_arg_value | 1 |
+-------------------------+----------+
1 row in set (0.00 sec)
Query OK, 0 rows affected (0.00 sec)
mysql> CALL test1('col_tmp2', 'tmp2');
+---------------------------------------------------------------------------------------------------------------------------------+
| @prepared_stmt |
+---------------------------------------------------------------------------------------------------------------------------------+
|
CREATE TEMPORARY TABLE tmp_test1
SELECT ? AS prepared_stmt_arg, col_tmp2 # AS constant_col_alias
FROM tmp2
|
+---------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
ERROR 1054 (42S22): Unknown column 'dev.tmp_test1.col_tmp1' in 'field list'
但是,如果取消注释列别名(删除#{1}}之前的#),一切正常。 (您可能需要向下滚动才能看到查询确定。)
AS constant_col_alias
答案 0 :(得分:1)
好吧它似乎是一个bug或一个功能(如果你想要的话)直到5.6版。
请参阅Bug #32868 Stored routines do not detect changes in meta-data.
解决方法:通过执行以下操作来刷新存储的例程缓存:
创建或替换视图tmpview
AS SELECT 1;
这是 SQLFiddle 演示MySql 5.1.X
这是 SQLFiddle 演示MySql 5.5.X
如果你发表评论CREATE OR REPLACE VIEW
tmpview AS SELECT 1
,你就会收到错误。
这是 SQLFiddle 演示MySql 5.6.X表明它不再是问题
<小时/> 现在你至少有这些选项:
SELECT *
使用显式列名。