Одним из вариантов рассмотрения является создание PROCEDURE
, в котором используются подготовленные операторы, а затем вызов хранимой процедуры из триггера.
Оператор SQL, который вы выполняете для получения значения из определенного столбца, ДОЛЖЕН иметь имя_столбца, указанное в тексте SQL; это не может быть выведено «динамически» при выполнении инструкции.
Чтобы добиться чего-то подобного, вам нужно запустить два отдельных оператора; один для получения column_name; второй - «SELECT column_name FROM
». И MySQL предоставил механизм для выполнения этого второго запроса - это подготовленный оператор.
Followup
Вот пример. Я попытался получить это в SQLFiddle, но не смог заставить его работать (он просто висел. Итак, вот результат от клиента командной строки mysql.
(Все приведенные ниже инструкции используют один и тот же разделитель //
потому, что мы не можем использовать точку с запятой в качестве разделителя для хранимой процедуры. в SQLFiddle, мы должны использовать один и тот же разделитель на всех операторов, а //
как раз случается быть один из вариантов в SQLFiddle.)
mysql> DELIMITER //
mysql> CREATE PROCEDURE foo(IN colname VARCHAR(255), IN id INT, OUT val VARCHAR(255))
-> BEGIN
-> -- handler for "Unknown column" and "No data" exceptions
-> DECLARE EXIT HANDLER FOR 1054, 1329 BEGIN SET val = NULL; END;
-> SET @sql = CONCAT('SELECT ',colname,' INTO @val FROM t WHERE id = ',id,' LIMIT 1');
-> PREPARE stmt FROM @sql;
-> EXECUTE stmt;
-> SET val = @val;
-> END//
Query OK, 0 rows affected (0.00 sec)
mysql> CREATE TABLE t (id INT, attr VARCHAR(4), ball VARCHAR(4))//
Query OK, 0 rows affected (0.11 sec)
mysql> INSERT INTO t VALUES (1, 'abcd','efgh'),(2,'ijkl','mnop')//
Query OK, 2 rows affected (0.00 sec)
Records: 2 Duplicates: 0 Warnings: 0
mysql> CALL foo('attr',1,@attr_1)//
Query OK, 0 rows affected (0.00 sec)
mysql> CALL foo('attr',2,@attr_2)//
Query OK, 0 rows affected (0.00 sec)
mysql> CALL foo('ball',1,@ball_1)//
Query OK, 0 rows affected (0.00 sec)
mysql> CALL foo('ball',2,@ball_2)//
Query OK, 0 rows affected (0.00 sec)
mysql> CALL foo('attr',777,@err_bad_id)//
Query OK, 0 rows affected (0.00 sec)
mysql> CALL foo('badcol',1,@err_badcol)//
Query OK, 0 rows affected (0.00 sec)
mysql> SELECT @attr_1
-> , @attr_2
-> , @ball_1
-> , @ball_2
-> , @err_bad_id
-> , @err_badcol//
+---------+---------+---------+---------+-------------+-------------+
| @attr_1 | @attr_2 | @ball_1 | @ball_2 | @err_bad_id | @err_badcol |
+---------+---------+---------+---------+-------------+-------------+
| abcd | ijkl | efgh | mnop | NULL | NULL |
+---------+---------+---------+---------+-------------+-------------+
1 row in set (0.00 sec)
mysql> DELIMITER ;
Nope. Ни в коем случае без подготовленных заявлений. – fancyPants
'SET @sql = CONCAT ('SELECT', @ DptTcn, 'FROM mytable3 WHERE tid =', @ tid);' Именно так вам нужно будет построить инструкцию SQL; текст SQL в вашей процедуре недействителен; неверно использовать переменные пользователя MySQL вместо идентификаторов (например,имена столбцов) в инструкции SQL. – spencer7593
Я изменил это, но проблема все еще там (команды не синхронизированы) – MiPnamic