我在mysql中注意到为什么准备动态查询需要我认为是全局变量。有没有办法将变量的范围限制在开始和结束语句之间?下面是我的测试脚本,当为limitCnt变量返回值10时。
delimiter //
drop procedure if exists testProc//
create procedure testProc ()
begin
-- DECLARE limitCnt INT default 10;
SET @limitCnt = 10;
PREPARE stmt FROM 'SELECT * FROM `participants` LIMIT ?';
EXECUTE stmt USING @limitCnt; -- the using part of the execute does not like the local variable
DEALLOCATE PREPARE stmt;
end//
call testProc()//
select @limitCnt//
drop procedure testProc//
delimiter ;
答案 0 :(得分:1)
如果您想使用局部变量,那么它们必须在begin...end
块中确定范围,但是如果您在某些begin
和{end
中嵌套了begin
和end
块{1}}阻止“所谓的”父begin
和end
块中声明的变量可以从“所谓的”子begin
和end
块中访问。请仔细阅读http://dev.mysql.com/doc/refman/5.0/en/local-variable-scope.html。
您在代码中执行的操作是设置名为limitCnt
的会话变量,该变量可在您的过程中的任何位置访问和使用,因此当您执行10
时,您将获得select @limitCnt
。
要使用本地变量,请使用declare var_name var_type
块中的begin...end
。
希望这能回答你的问题。
答案 1 :(得分:0)
根据MySQL 5.0 Documentation,您不能在EXECUTE ... USING
语句中使用局部变量。请参阅以下文档中有关如何使用该语句的摘录:
EXECUTE stmt_name
[USING @var_name [, @var_name] ...]
您必须使用@前缀。
答案 2 :(得分:0)
没有办法绕过它。这是MySql中的设计。
本地/存储过程/存储的函数级变量
PREPARE
来自EXECUTE
USING
醇>
<强> PREPARE Syntax 强>
...语句名称不区分大小写。 preparable_stmt是一个 包含SQL文本的字符串文字或用户变量 声明。 ......在存储的程序上下文中准备的语句不能引用存储 过程或函数参数或局部变量因为它们去了 当程序结束并且不可用时,范围超出范围 稍后在程序外执行的语句。 ...
<强> EXECUTE Syntax 强>
... 参数值只能由用户变量和USING提供 子句的名称必须与参数的数量完全相同 声明中的标记。 ...
用户变量具有会话范围。
现在,为了解决您的问题,只需在使用之前将值明确设置为用户定义的变量。就像您为@limitCnt
分配默认值一样。
SET @limitCnt = 10;
此外,您可以在存储过程/存储函数/脚本的末尾为此变量设置NULL
的值。
SET @limitCnt = NULL;
这是 SQLFiddle 演示