2013-07-17 3 views
1

У меня есть таблица «mytable», которая содержит поле «columnname», которое является именем столбца в mytable2.Mysql Triggers, объявить переменную и использовать ее как имя столбца

Я использую этот для выбора:

SET @DptScn = (SELECT columnname FROM mytable WHERE tablename = 'CustomTableName' AND fieldlabel = 'CustomField'); 
SET @identifiedid=144; 

, но, когда я пытаюсь:

SELECT @DptScn FROM mytable2 WHERE identifiedid = @identifiedid; 

это даст мне не содержание поля, но имя containted в переменную @DptScn. ..

Любые советы? я не могу использовать подготовленное заявление, потому что я нахожусь в Trigger ...

UPDATE:

Как было предложено spencer7593 я создаю процедуру:

DROP PROCEDURE IF EXISTS p_t; 
DELIMITER $$ 
CREATE PROCEDURE p_t (IN DptTcn VARCHAR(255), IN tid INT, OUT tT INT) 
BEGIN 
    SET @DptTcn = DptTcn; 
    SET @tid = tid; 
    SET @sql = CONCAT('SELECT @DptTcn FROM mytable3 WHERE tid = @tid'); 
    PREPARE stmt FROM @sql; 
    EXECUTE stmt; 
END$$ 
DELIMITER ; 

Тогда я попробовать :

SET @DptTcn = (SELECT columnname mytable WHERE tablename = 'CustomTableName' AND fieldlabel = 'CustomField'); 
SET @identifiedid=145; 
CALL proc_ticket(@DptTcn, @identifiedid, @DptT); 

Но я получаю:

#2014 - Commands out of sync; you can't run this command now 
+0

Nope. Ни в коем случае без подготовленных заявлений. – fancyPants

+1

'SET @sql = CONCAT ('SELECT', @ DptTcn, 'FROM mytable3 WHERE tid =', @ tid);' Именно так вам нужно будет построить инструкцию SQL; текст SQL в вашей процедуре недействителен; неверно использовать переменные пользователя MySQL вместо идентификаторов (например,имена столбцов) в инструкции SQL. – spencer7593

+0

Я изменил это, но проблема все еще там (команды не синхронизированы) – MiPnamic

ответ

1

Одним из вариантов рассмотрения является создание 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 ; 
+0

Я обновил ответ, следуя вашему предложению ... но есть кое-что, что я не понимаю ... – MiPnamic

+0

@MiPnamic: Я не мог заставить это построить SQL-скрипт (он просто зависает, говоря «Building») поэтому я вложил сюда результат из командной строки mysql. Обратите внимание, что оператор SQL сформулирован как строка, а строка, которая выполняется, имеет только одну пользовательскую переменную, и это тот оператор SQL, который присваивает значение. также включает обработчики исключений для исключения «Нет данных» (поднятые, когда запрос не возвращает строку), и исключение «Неизвестный столбец» (возникает, когда указанный столбец не существует в таблице). обрабатывать exce по-другому. – spencer7593

+0

IT полностью работает !!!! – MiPnamic

0

вы должны создать СП и дать имя столбца.

create proc dbo.TestGetData(@DptScn nvarchar(256)) 
as 
    begin 
    set nocount on 
    DECLARE @SQL NVARCHAR(MAX) 
    SET @SQL = 'SELECT @DptScn FROM mytable2 WHERE identifiedid = 144' 
    exec sp_executesql @SQL, N'@DptScn nvarchar(256)', @DptScn [email protected] 
end 

Затем

exec dbo.TestGetData 'Column1' 
+0

Могу я «exec dbo.TestGetData @DptScn» в моем триггере? – MiPnamic

+0

Этот синтаксис предназначен для Microsoft SQL Server, а не для MySQL. – spencer7593

Смежные вопросы