2023-03-08

MySQL 遭遇奇怪的 VIEW ERROR 1356 view 'xxx' references invalid table(s) or column(s) or function(s) or definer/invoker...

 環境說明

  • windows server 2019
  • apache 2.4
  • mysql 8.0.28
  • Laravel 8, php 7.4
---
吃完晚餐後,突然接到老闆的 line call 說客戶系統那邊有關 mes 的功能頁面都會出現 server error 的 alarm 訊息,讓我去看看

查看 laravel.log 後發現反饋的訊息是如標題的
view 'xxx' references invalid table(s) or column(s) or function(s) or definer/invoker...

的訊息

看到就利用 CLI 連入 mysql engine 查看 user 權限,但利用 mysql information_schema 查權限,發現都沒有奇怪的地方。

該套系統除了客戶的環境有用,在公司的 aws 的環境上也有用,但沒有同樣的問題發生。

後來直接針對一頁所使用的 api 反查到相關 laravel 的 controller/model 中進行斷點檢查時發現,在經過特定的一行程式後才會出現該異常,在該行程式之前把結果列印出來是正常的…

該行程式主要是進行工單有強制停止屬性的就排除掉,但該系統有分總工單跟明細工單兩種模式,我當下把系統切到明細工單再來瀏覽,發現沒有異常…

而在總工單模式下,要過濾強制停止的工單的作法,是在總工單的 view 表中,有用 JSON_LENGTH() 去把總工單中有多少明細工單的數量獨立出來一個欄位,然後在查表時,先計算總工單中有強制停止屬性的明細工單的數量如果與總工單中明細數量相等的話,就代表該總工單要被過濾掉。

但問題就是發生在這個「比較」上, 假設我是這樣設計 view 表的(假設是叫 view_a)

SELECT JSON_LENGTH(`總工單中的明細工單資料集成`) AS `明細工單總數` FROM `總工單`;

以上存為 view 表

然後在工單查詢中是利用以下的查詢進行過濾

SELECT * FROM `view_a` WHERE JSON_LENGTH( IFNULL( JSON_EXTRACT(`總工單中的明細工單資料集成`, '$.*.強制停止'), '[]')) < `明細工單總數`;

這樣就會出現 1356 的 error

改成

SELECT * FROM `view_a` WHERE JSON_LENGTH( IFNULL( JSON_EXTRACT(`總工單中的明細工單資料集成`, '$.*.強制停止'), '[]')) <JSON_LENGTH(`總工單中的明細工單資料集成`);

就可以正常的執行下去

實在奇怪???