mysql准备:会话变量vs参数&局部变量

时间:2013-08-16 16:08:09

标签: mysql prepared-statement

我正在使用存储过程并准备语句。我想发送参数来定义从select语句返回的列。如果我使用会话变量而不替换变量,则此方法有效。我可以解决这个问题,但我想了解这个问题。以下是示例:

这有效:

DELIMITER $$
DROP PROCEDURE IF EXISTS `pnlByTheme` $$
CREATE PROCEDURE `pnlByTheme`(IN param VARCHAR(50))
BEGIN
  set @sqlStmt = concat("select ",param," from pnl_aggregate");
  prepare stmt from @sqlStmt;
  execute stmt;
deallocate prepare stmt;
END $$
DELIMITER ;

当我调用pnlByTheme('label')时,我从pnl_aggregate获取select标签的结果,就像我从命令行那样。如果我将set语句更改为:

set @sqlStmt = "select ? from pnl_aggregate";

然后我将execute语句更改为:

execute stmt using param;

mysql不喜欢这样,也不会创建程序。如果我改为:

DELIMITER $$

DROP PROCEDURE IF EXISTS `pnlByTheme` $$
CREATE PROCEDURE `pnlByTheme`(IN param VARCHAR(50))
BEGIN
  set @p = param;
  set @sqlStmt = "select ? from pnl_aggregate";
  prepare stmt from @sqlStmt;
  execute stmt using @p;
deallocate prepare stmt;
END $$

DELIMITER ;

将创建该过程。为什么?什么是奇怪的(对我来说,无论如何)是调用的结果

call pnlbytheme('label');
对于每一行,

只是字面上的“标签”,而不是我要查找的实际数据。我可以使用concat轻松解决这个问题,但想要了解。请帮忙。

1 个答案:

答案 0 :(得分:1)

好的,非常感谢那些看上去的人。在发布相关问题后,我找到了答案。有时我们(或至少我)并不总是知道如何搜索我们想要的东西。无论如何,这里有两个答案:

1)准备好的陈述是全球会议。请参阅Dynamic MySQL with local variableshttp://dev.mysql.com/doc/refman/5.1/en/sql-syntax-prepared-statements.html(查找“准备好的声明对会话也是全局的。”)。虽然我对此并不是100%明确,但结果是需要会话变量。答案是贾斯汀格兰特。

2)“参数标记只能在数据值出现的地方使用,而不能用于SQL关键字,标识符等。”来自http://dev.mysql.com/doc/refman/5.7/en/prepare.html,由Devart在此处mysql stored procedure oddity回答。

我还发现MySQL: @variable vs. variable. Whats the difference?有帮助。谢谢,Quassnoi。