这个查询应该做什么? (为什么会失败?)

时间:2016-02-26 22:04:12

标签: mysql sql

我的任务是恢复这一旧版旧软件。 它曾经在旧的服务器(2012)上运行,它已经以丑陋的方式死亡(硬盘故障)。 在此服务器死亡之前,代码工作没有问题。

我正在从备份重建MySQL数据库和数据。

但是,一个查询不起作用并因错误而失败:Query preparation failed: Unknown column '_operationId' in 'where clause'。有问题的查询是:

SELECT
  @r AS _operationId
, @r := (
    SELECT
      operationId
    FROM operations
    WHERE operationId = _operationId
  ) AS includesOperationId
FROM (SELECT  @r := %i) AS tmp
INNER JOIN operations
WHERE @r > 0 AND @r IS NOT NULL

根据我的理解,查询尝试连接回自己构建某种树?

出于某种原因,此查询必须在某些先前版本的MySQL(5.0 ??)上运行,但对于当前版本(MySQL 5.7),查询将失败。

有没有“mysql低语者”可以向我解释:

  1. 查询尝试做什么?
  2. 为什么它在某些先前版本上工作但不再适用?
  3. 如何更改查询以使其再次有效?
  4. 提前感谢一百万。

    更新
    operations表定义和数据:

    +-------------+---------------------+------+-----+---------+----------------+
    | Field       | Type                | Null | Key | Default | Extra          |
    +-------------+---------------------+------+-----+---------+----------------+
    | operationId | bigint(20) unsigned | NO   | PRI | NULL    | auto_increment |
    | operation   | varchar(40)         | NO   | UNI | NULL    |                |
    | description | text                | YES  |     | NULL    |                |
    +-------------+---------------------+------+-----+---------+----------------+
    

    <子>

    +-------------+-----------+-------------+
    | operationId | operation | description |
    +-------------+-----------+-------------+
    |           1 | add       | NULL        |
    |           2 | delete    | NULL        |
    |           3 | edit      | NULL        |
    |           4 | view      | NULL        |
    |           5 | disable   | NULL        |
    |           6 | execute   | NULL        |
    +-------------+-----------+-------------+
    

1 个答案:

答案 0 :(得分:1)

评论太长了。

查询正在尝试进行某种树遍历。我不知道它适用于任何版本的MySQL,但我最好的猜测是意图是这样的:

SELECT @r AS _operationId,
       @r := (SELECT operationId
              FROM operations
              WHERE operationId = @r
             ) AS includesOperationId
FROM operations CROSS JOIN
     (SELECT @r := %i) params
WHERE @r > 0 AND @r IS NOT NULL;

话虽如此,如果发生工作,则无法保证它会再次运行或在其他版本的MySQL中运行。这违反了使用变量的两个规则:

  • SELECT中一个表达式中指定的变量不应在另一个表达式中使用。未定义表达式的评估顺序,因此可以按任何顺序评估表达式。
  • 无法保证何时评估使用变量的WHERE子句中的条件,并且无法保证对SELECT进行某种“顺序”评估。

子查询也存在问题。

好消息是,如果operations没有名为_operationId的列,那么查询应该在所有版本的MySQL上失败,其中包含未定义的列类型的错误(尽管旧版本可能做了一些时髦的事情)

坏消息是,如果您想要在MySQL中使用层次结构,则需要更改数据结构或使用存储过程。