MySQL manual on user variables说
作为一般规则,除了在SET语句中,您不应该为用户变量赋值并在同一语句中读取值。例如,要增加变量,这没关系:
SET @a = @a + 1;
对于其他语句,例如SELECT,您可能会得到您期望的结果,但这不能保证。在下面的语句中,您可能会认为MySQL将首先评估@a,然后再进行一次分配:
SELECT @a, @a:=@a+1, ...;
但是,涉及用户变量的表达式的评估顺序是未定义的。
这显然是在比较苹果和橘子。 SELECT @a:= @ a + 1;将是等效的,并且与SET @ a = @ a + 1一样好,因为在将其值赋给@a之前总是要评估@ a + 1。
但是,如果我们对SET做同样的事情,即。
SET @b=@a,@a=@a+1;
是否保证@b的值在执行语句之前包含@a的值?或者它可以包含递增的值?
可以提出以下问题:
表达式是否会从左到右进行评估? IE浏览器。之后
SET @a =(@v:='x'), @b = (@v:='y');
@v保证是' y'
分配是从左到右完成的?即,
之后SET @v='x',@v='y';
@v保证是' y'
所有评估都会在所有作业之前严格执行吗?即,
之后SET @a='x',@v=@a,@a='y';
是否保证在执行语句之前包含@a的值? ("如果SET语句中的任何变量赋值失败,则整个语句失败并且没有变量更改"来自手册建议这一点,尽管它也允许SET保存旧值并在赋值时恢复它们失败。)
虽然MySQL manual on stored program variables表示可以使用SET语句直接设置'变量。请参阅Section 13.7.4.1, “SET Syntax for Variable Assignment”。',我注意到,当我这样做时
DELIMITER //
CREATE PROCEDURE TEST_SET()
SQL SECURITY INVOKER
BEGIN
SET @v='BEFORE',@a='BEFORE';
SET @a='x',@v=@a,@a='y',@a=(SELECT * FROM doesntexist);
END//
DELIMITER ;
然后
CALL TEST_SET();
SELECT @a,@v;
显然,SET从左到右严格交替进行评估和分配,直到遇到错误。这与在存储过程外执行SET的行为不同,并且没有"如果SET语句中的任何变量赋值失败,则......没有变量被更改。"我很困惑。
MySQL manual on SET无法解答这些问题。
请注意,它无助于尝试使用MySQL的语句并查看获得的结果。我想知道什么是保证。