在MySQL 8.0.23中,我注意到当我使用这样的用户变量(注意这不是真正的查询).
mysql> set @row = 0;
Query OK, 0 rows affected (0.01 sec)
mysql> select @row := @row + 1;
+------------------+
| @row := @row + 1 |
+------------------+
| 1 |
+------------------+
1 row in set, 1 warning (0.00 sec)我会收到这个警告:
| Warning | 1287 | Setting user variables within expressions is deprecated and will be removed in a future release. Consider alternatives: 'SET variable=expression, ...', or 'SELECT expression(s) INTO variables(s)'.实际上,如果不将其转换为公共表表达式,则上述查询的更复杂版本将无法给出适当的结果。
但是,当我在MySQL 8.0.28及以后测试这个问题时,我不再收到这个警告了,实际上原始查询再次工作了!我看了看发布说明,我看不出它实际上是在哪里恢复的。当这个特定的行为被改变或恢复时,有人知道我在哪里可以得到更多的信息吗?
发布于 2023-01-19 19:52:47
https://bugs.mysql.com/bug.php?id=104918
8.0.28的发行说明提到了修复:
当一个条件被推倒时,评估子查询的选择列表中的用户变量的赋值的结果有时会受到影响。由于这个原因,我们现在防止了条件下推对于带有分配给用户变量的语句。
您提到,在您的示例中,“查询的更复杂版本”不会给出正确的结果。我假设错误的查询涉及子查询。
除了这个错误,在MySQL 8.0中,您应该使用ROW_NUMBER()窗口函数而不是用户变量来生成行号。
发布于 2023-01-19 19:13:23
对于简单表达式,SET工作得很好:
SET @row = @row + 1;如果你需要一张桌子,就说出来。
(:=在SET工作。=指的是在SELECT中使用时不同的东西。)
2018年的变化-10-22 8.0.13总可用性-重要变化
现在不推荐在设置以外的语句中设置用户变量,因为这里列出的问题包括:未定义涉及用户变量的表达式的计算顺序。变量的默认结果类型基于语句开头的类型,如果在语句开始时为包含一个类型的值的变量在同一语句中分配了一个不同类型的新值,则可能会产生意外效果。当引用在select表达式列表中分配值的变量时,有、GROUP和ORDER子句不能按预期工作,因为表达式是在客户端上计算的,因此可以使用来自上一行的陈旧列值。出于向后兼容性的考虑,SELECT @var、@var:=@var+1等语法在MySQL 8.0中仍然被接受,但在以后的版本中可能会被删除。
https://dba.stackexchange.com/questions/322328
复制相似问题