2013-07-17 58 views
1

我有包含「columnname」字段的表「mytable」,這是mytable2中列的名稱。Mysql觸發器,聲明一個變量並將其用作列名稱

我用這一個選擇:

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

,但是,當我嘗試:

SELECT @DptScn FROM mytable2 WHERE identifiedid = @identifiedid; 

這給我場的不是內容而是containted到變量@DptScn名稱。 ..

有什麼建議嗎? 我不能使用預處理語句,因爲我在一個觸發器是...

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

沒有。沒有準備好的陳述沒辦法。 – 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;這不能在執行語句時「動態」派生。

要實現這樣的事情,您需要運行兩個單獨的語句;一個獲取column_name;第二個到「SELECT column_name FROM」。 MySQL提供的執行第二個查詢的機制是一個準備好的語句。


跟進

下面是一個例子。我試圖用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小提琴(它只是掛起,說「建設」),所以我在這裏把mysql命令行客戶端的輸出粘貼到這裏,注意SQL語句是以字符串的形式表示的;被執行的字符串只有一個用戶變量,這是SQL語句賦值的地方。還包含「無數據」異常(在查詢未返回行時引發)的異常處理程序以及「未知列」異常(當表中不存在指定的列時引發)。處理exce一種不同的方式。 – spencer7593

+0

它完全可以工作! – MiPnamic

0

你應該創建一個SP並給出列名。

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 

Then

exec dbo.TestGetData 'Column1' 
+0

我可以在我的觸發器中「exec dbo.TestGetData @DptScn」嗎? – MiPnamic

+0

此語法適用於Microsoft SQL Server,不適用於MySQL。 – spencer7593