2016-02-26 193 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