2016-02-26 265 views
0

我的任务是重振这一旧版软件。 它曾经运行在一个旧的服务器上(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. 如何更改查询以使其重新工作?

感谢提前一百万。

更新:
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  | 
+-------------+-----------+-------------+ 
+0

我是一个SQL Server的人,所以可能无法帮助,但是如果您提供一些示例数据,也许是表模式,那对于那些专业的MySQL来说,了解到底是怎么回事。 – 2016-02-26 22:19:16

+0

我怀疑这个查询是否适用于任何版本,因为它是。 – Mihai

+0

你的代码表明'_operationid'也是环境中的一个变量。在同一个查询中使用会话变量(使用'@'和过程变量)确实很奇怪。 –

回答

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中的层次结构,则需要更改数据结构或使用存储过程。

+0

BUMP!我喜欢这个答案!在这里,接受我的赞扬:)现在“Ifu”能够澄清的是,什么和在哪里调用SP,我们怎么想,调用者期望的结果集是什么样的? – 2016-02-26 22:34:52

+0

我期望内部查询中的'_operationId'以某种方式引用外部查询中的'_operationId',或者至少它在旧的mysql版本中是这样做的。 – ifu

+0

@Mark,代码似乎期望两列,在两者中都有一个operationId。我认为这些ID预计是分层次的。 – ifu