SET

时间:2017-06-29 11:19:04

标签: mysql sql

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的值?或者它可以包含递增的值?

可以提出以下问题:

  1. 表达式是否会从左到右进行评估? IE浏览器。之后

    SET @a =(@v:='x'), @b = (@v:='y');
    

    @v保证是' y'

  2. 分配是从左到右完成的?即,

    之后
    SET @v='x',@v='y';
    

    @v保证是' y'

  3. 所有评估都会在所有作业之前严格执行吗?即,

    之后
    SET @a='x',@v=@a,@a='y';
    

    是否保证在执行语句之前包含@a的值? ("如果SET语句中的任何变量赋值失败,则整个语句失败并且没有变量更改"来自手册建议这一点,尽管它也允许SET保存旧值并在赋值时恢复它们失败。)

  4. 虽然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的语句并查看获得的结果。我想知道什么是保证。

0 个答案:

没有答案