【问题标题】:User-Defined Variable Assignment difference between MySQL and MariaDBMySQL 和 MariaDB 之间的用户定义变量分配区别
【发布时间】:2021-03-27 08:15:03
【问题描述】:

当然,我们之前已经完成了我们的工作,并在这个社区或网络上搜索过类似的帖子,但我们一无所获。

问题:

我们对当前的托管服务提供商不满意,必须做出改变。在我们的数据库从 MySQL 5.7 切换到 MariaDB 10.3 的过程中,我们发现了 SET 处理的差异,这在 MySQL 中非常有效。

SQL 代码:

SET @sb = 0;

SELECT art,sb
FROM ARTICLE
WHERE(@sb:=sb) > 700 AND @sb <= 1000 >AND art = 'AM';

MySQL 结果:

art sb
AM 900.00
AM 960.00
AM 1000.00
AM 770.00
AM 800.00
the list is much longer...

MariaDB 结果:

art sb
AM 770.00
AM 960.00
AM 1200.00
AM 3000.00
only 10 rows...

其实它们之间是有区别的。

但我们想知道:

  1. 我们可以在 MariaDB 中进行配置,以便在 MySQL 中得到相同的结果吗?
  2. 我们是否应该将 MariaDB 中的 Set 处理替换为另一个?

【问题讨论】:

  • SELECT 列表或 WHERE 子句中的操作顺序从未被定义为从左到右,因此您不应该依赖于在阅读之前发生的分配时间。
  • 为什么需要使用@sb?为什么不能使用WHERE sb &gt; 700 AND sm &lt;= 1000
  • 这只是一个例子。它是声明的历史发展。我们只想知道在 MariaDB 中是否或如何处理它。

标签: mysql sql mariadb


【解决方案1】:

不,这是不可能的。

其实MySQL documentation warns关于SQL语句里面变量赋值的使用:

涉及用户变量的表达式的计算顺序未定义。例如,不能保证SELECT @a, @a:=@a+1 先评估@a,然后再执行分配。

更重要的是,这是一个可能会被删除的“功能”:

以前的 MySQL 版本可以在 SET 以外的语句中为用户变量赋值。 MySQL 8.0 支持此功能以实现向后兼容性,但可能会在 MySQL 的未来版本中删除。

所以你不应该依赖它,重写你的查询。

【讨论】:

    【解决方案2】:

    MySQL documentation 在这一点上非常清楚:

    作为一般规则,除了在 SET 语句中,您不应该为用户变量赋值并在同一语句中读取值。

    您的代码曾经有效是一种巧合。此类警告的原因是行为可能会在版本之间发生变化;甚至在同一数据库上运行的结果可能不一致。

    您应该用窗口函数替换变量。具体功能有点不清楚。样本数据、期望的结果以及对结果的清晰解释总是有帮助的。

    【讨论】:

      猜你喜欢
      • 2015-06-04
      • 2018-09-27
      • 2016-08-12
      • 2019-07-25
      • 1970-01-01
      • 1970-01-01
      • 2018-10-23
      • 2012-06-24
      • 2023-03-22
      相关资源
      最近更新 更多