在MySQL WHERE中设置和使用变量

时间:2017-05-17 09:23:58

标签: mysql

如果我在MySQL 5.7.16上执行以下查询,那么结果集包含一行值为2的行,这是预期的:

SELECT *
FROM (SELECT 1 as x UNION SELECT 2 UNION SELECT 3) AS t
WHERE ( 2 IS NULL OR t.x = 2 )
;
-- Resultset: 1 row, x = 2

现在,我想在准备好的语句中使用这个逻辑,比如? IS NULL OR t.x = ?。所以你看到相同的参数出现两次。因此,我应用了我在SO上找到的建议(我不记得确切位置):将参数放在MySQL会话变量中,然后使用它:

SELECT *
FROM (SELECT 1 as x UNION SELECT 2 UNION SELECT 3) AS t
WHERE ( (@x := 2) IS NULL OR t.x = @x )
;
-- Resultset: 0 row

但是失败了:没有返回任何行。当我还选择@x变量时,为了查看正在进行的操作,我得到NULL的{​​{1}}值:

@x

因此,当放入SELECT @x FROM (SELECT 1 as x UNION SELECT 2 UNION SELECT 3) AS t WHERE ( (@x := 2) IS NULL OR t.x = 2 ) ; -- Resultset: 1 row, @x = NULL 时,似乎没有设置变量?到底是怎么回事?

我可以在WHERE内制作INNER JOIN (SELECT 2 AS x) AS params并使用params.x,但我想了解WHERE中发生了什么。

1 个答案:

答案 0 :(得分:1)

这里发生的事情是WHERE内的执行顺序是任意。这意味着使用

(@x := 2) IS NULL OR t.x = 2

无法保证首先执行@x := 2

要正确初始化变量,请使用CROSS JOIN

SELECT *
FROM (SELECT 1 as x UNION SELECT 2 UNION SELECT 3) AS t
CROSS JOIN (SELECT @x := 2) AS v
WHERE ( @x IS NULL OR t.x = @x )