我們一起聊聊奇怪的SQL問題+1
你好,我是yes。
我的 VIP 用戶又拋給我一個 SQL 問題,我很激動,因為素材又來了:
我一看,這個表沒什么花頭,不就是沒設置主鍵嗎,MySQL 會默認生成一個主鍵,這跟 delete 不掉數據好像也沒啥關系。
然后他說:
delete from a where device_id = '1239898' and task_id = '00111133445566';
這樣刪除不掉。
但是用 navicat 界面選擇某一行點擊刪除可以刪掉,然后他發現這樣操作刪除的 SQL 在尾部加上了 ESCAPE '#';
delete from a where device_id = '1239898' and task_id like '00111133445566' ESCAPE '#';
不知道為啥在界面手動刪除用的是 like ,但是先不管,反正根據這個現象他暫時得出了一個結論,這個表的數據加ESCAPE '#'; 才刪的掉。
我一聽更興奮了,這是什么奇怪的操作!
ESCAPE 是什么?
這個 ESCAPE 是一個關鍵字,它的作用其實很簡單:替代轉義的字符。
我們都知道跟 like 有關的 % 的作用,它能匹配任意多個字符。
比如 select * from a where name like '陳%';
這條語句就能把 a 表中姓陳的人都查找出來。
那現在有個人他叫“陳%2”,你只想找“陳%”開頭的 name。
此時你就不能用 like '陳%',你需要用 like '陳 \ %%':
這里的 \ 就是轉義符,它的作用是把緊跟后面的這個字符轉義成正常的字符,不再具有它之前的含義(像 %之前的含義就是匹配任意多個字符)。
而 ESCAPE 的作用就是聲明另一個字符來替換 \ 。
比如 select * from a where name like '陳#%%' ESCAPE "#";
這樣一聲明,# 就達到了 \ 的效果。
回到問題上來
現在我們已經明白了 ESCAPE 的作用,那么它跟開頭的問題有什么關系嗎?
我不知道,但是我很興奮,我開始瘋狂查閱資料。
google 無。
chatgpt 無。
newbing無。
MySQL官網無。
然后開始懷疑了:
好像看起來沒什么特別的。
然后我又過了一遍跟他的聊天記錄。
我直呼好家伙!!
他寫的 SQL 是:
實際的數據是 :
所以他把兩個條件寫錯了,task_id 是 1239898,device_id 才是那個一長串!!!
我估計這位同學之所以沒看出來的原因是客戶端手動刪除的操作能刪掉:
且產生了奇怪的 SQL,莫名加了 ESCAPE '#',讓我們的這位同學一下子陷入了沉思。
實際上手動刪除的 SQL 這么奇怪就是因為表沒有主鍵,不然正常手動的刪除 SQL 上 where 條件肯定是 id =xxx。
至于為什么加了 ESCAPE '#' 其實我也沒懂,我查了查也也沒查到。
如果知道的大佬歡迎留言指導下!
最后
所以,這并不是一個奇怪的 SQL 問題,只是一個小疏忽。
其實這種問題在編程上很常見,比如在 postman 調試的時候,分頁數據寫反了,pageSize寫了1,pageNumer 寫了 10 ,導致怎么查都沒數據,怎么 debug 都看蒙了。
因為疏忽產生了很多奇奇怪怪、五花八門的問題,然后花了很多時間去找答案,還找不到。
最終沉下心來總的再過一遍才會發現,或者只能求助于同事。
我知道有問題,但是深陷其中當局者迷,花了兩個小時還沒解決,同事 10s 就能看出來。
所以遇到事情不要不好意思,要主動求助同事,不然那兩個小時是真的痛苦!