1

我有表“mytable”,其中包含“columnname”字段,它是 mytable2 中列的名称。

我使用这个进行选择:

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

但是,当我尝试时:

SELECT @DptScn FROM mytable2 WHERE identifiedid = @identifiedid;

这给我的不是字段的内容,而是包含在变量@DptScn 中的名称...

有什么建议吗?我不能使用准备好的语句,因为我在触发器中......

更新:

正如 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
4

2 回答 2

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 ;
于 2013-07-17T18:18:00.177 回答
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 =@DptScn 
end

然后

exec dbo.TestGetData 'Column1'
于 2013-07-17T18:32:05.017 回答