我正在使用存储过程并准备语句 . 我想发送参数来定义从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 回答
好的,非常感谢那些看上去的人 . 在发布相关问题后,我找到了答案 . 有时我们(或至少我)并不总是知道如何搜索我们想要的东西 . 无论如何,这里有两个答案:
1)准备好的陈述是全球 Session . 见Dynamic MySQL with local variables和http://dev.mysql.com/doc/refman/5.1/en/sql-syntax-prepared-statements.html(寻找"A prepared statement is also global to the session.") . 虽然我对此并不是100%明确,但结果是需要会话变量 . 答案是贾斯汀格兰特 .
2)"Parameter markers can be used only where data values should appear, not for SQL keywords, identifiers, and so forth."来自http://dev.mysql.com/doc/refman/5.7/en/prepare.html,由Devart回答了这里mysql stored procedure oddity .
我也发现MySQL: @variable vs. variable. Whats the difference?很有帮助 . 谢谢,Quassnoi .