【问题标题】:mysql prepare: session variables vs parameters & local variablesmysql准备:会话变量与参数和局部变量
【发布时间】:2013-08-16 16:08:09
【问题描述】:

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

这行得通:

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 中获得选择标签的结果,就像从命令行中一样。如果我将 set 语句更改为:

set @sqlStmt = "select ? from pnl_aggregate";

然后我将执行语句更改为:

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 轻松解决此问题,但想了解。请帮忙。

【问题讨论】:

  • 我找到了部分答案(是的,我在发布之前确实看过)。见stackoverflow.com/questions/1471570/…。这解释了准备好的语句是会话全局的,它似乎可以转换为使用会话变量。但我仍然不知道为什么 @p 的替换不能按预期工作。

标签: mysql prepared-statement


【解决方案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。

【讨论】:

    猜你喜欢
    • 2011-04-16
    • 1970-01-01
    • 2016-10-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-20
    相关资源
    最近更新 更多