MySQL 5.2, CentOS 6.4.MySQL SELECT * не работает во временной таблице, созданной PREPARE, с использованием динамических имен столбцов и таблиц после первого прохода
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'
Однако, если вы раскомментировать псевдоним столбца (удалить # непосредственно перед AS constant_col_alias
), все работает хорошо. (Вы, возможно, потребуется прокрутить вниз, чтобы увидеть Query OK.)
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 | constant_col_alias |
+-------------------------+--------------------+
| 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)
+-------------------------+--------------------+
| prepared_stmt_arg | constant_col_alias |
+-------------------------+--------------------+
| prepared_stmt_arg_value | 2 |
+-------------------------+--------------------+
1 row in set (0.00 sec)
Query OK, 0 rows affected (0.00 sec)
ли вы на самом деле имел в виду, чтобы иметь столбец с именем '?' Или вы имели в виду, чтобы это было заполнитель? – peterm
Просто placeholder. Я только ставил его там, чтобы проиллюстрировать, что само подготовленное утверждение, похоже, функционирует должным образом. Я удалю его, поскольку это не относится к проблеме. – Michael