臥槽!我一個(gè) SQL 老 Boy 竟然栽在 Not IN 上
點(diǎn)擊藍(lán)色“有關(guān)SQL”關(guān)注我喲
加個(gè)“星標(biāo)”,天天與10000人一起快樂(lè)成長(zhǎng)

圖 |?Lenis
是的,大年三十,我踩中一個(gè) Bug.
平時(shí)風(fēng)平浪靜,今天給我找茬。這一天是什么日子?
全中國(guó)14億人,都在等著這一天。父親大人,母親大人,老婆大人,滿(mǎn)堂老少齊集一屋,都在等著我發(fā)紅包,連鄰居家牙沒(méi)長(zhǎng)齊的娃兒,都在門(mén)口笑著,等我的糖吃。
現(xiàn)在居然出現(xiàn)了一個(gè)Bug!
箭矢般的歸心,嗷嗷叫的告警,就像 2 個(gè)大巴掌,左手一記勾拳,右手一記銷(xiāo)魂掌。打得我就像紫霞仙子與牛魔王飛進(jìn)了肚子,表面冷靜無(wú)比,肚里翻江倒海。
按照往年的規(guī)律,年前最后一天不發(fā)代碼。不做事,哪來(lái)錯(cuò)。以這樣的物理措施,保障了新年的祥和,一年又一年。
但今年特殊,原地過(guò)年,想著年前把事做完整。結(jié)果上午貪心小朋友找我聊聊天,洗了個(gè)腦,不自覺(jué)的又加了幾百行代碼。
可,偏偏,心里怕啥,就來(lái)啥。下午就爆Bug.
好了,不給自己的錯(cuò)誤,找借口。這個(gè) SQL Bug 其實(shí)也不高深。舉個(gè)簡(jiǎn)單的例子,就像下面這樣:
SELECT?*?
FROM?dbo.Products??
WHERE?Brand?NOT?IN?(
?SELECT?Brand?
?FROM?dbo.Products??
?WHERE?NAME?=??'Transformer'??
?)
這段 SQL 的目的,是從玩具產(chǎn)品中,查找不是 Transformer 品牌商的玩具。
本來(lái)是自信滿(mǎn)滿(mǎn),寫(xiě)完提交,毫無(wú)懸念。但 QA 硬生生打回來(lái)了。
附上的評(píng)語(yǔ),口氣異常輕蔑:
你居然讓我找到如此簡(jiǎn)單的 bug,毫無(wú)成就感
嗯,好吧。我承認(rèn)!栽了……
表面上看著一點(diǎn)錯(cuò)沒(méi)有,邏輯清晰,語(yǔ)法正確通順,那為什么會(huì)錯(cuò)了呢?
原因是這樣的:
SELECT?Brand?
FROM?dbo.Products??
WHERE?NAME?LIKE?'Transformer%'????
?
在子查詢(xún)中,如果不做 Brand 的約束,它有機(jī)會(huì)是 NULL 值。子查詢(xún)返回 NULL 值,則無(wú)果。
以我做了3年多老測(cè)試的角度看,QA絕不能發(fā)現(xiàn)這么奇怪的Bug. 于是我好奇打聽(tīng),他們?cè)趺礈y(cè)的,才發(fā)現(xiàn),原來(lái)他們有神器。
這,就是 SonarQube. 本文真正的主角。
之前我也寫(xiě)過(guò),要注意對(duì) SQL 運(yùn)行的“事后”做監(jiān)控,提高數(shù)據(jù)庫(kù)運(yùn)行“三高”:高可用,高穩(wěn)定,高性能。
但,沒(méi)有涉及到 SQL “事前”審核。經(jīng)某知友(知乎網(wǎng)友)提醒,SQL 審核最好做在部署代碼前。
這款 SonarQube 代碼審核平臺(tái),正好可以滿(mǎn)足需求。它支持 T-SQL, PL/SQL 等常用 SQL 方言。當(dāng)然,其他近 30 種編程語(yǔ)言,Java,C#, Python, C/C++等,都是支持的。
SonarQube 真正折服我的,是全自動(dòng)代碼測(cè)試。它能找到隱藏的Bug,安全漏洞,測(cè)試覆蓋率,怪味道代碼,還有代碼復(fù)用場(chǎng)景,甚至能精確到某幾個(gè)存儲(chǔ)過(guò)程的代碼行。



如果有這樣的自動(dòng)化查錯(cuò)機(jī)器,你還怕別人說(shuō)你的代碼爛么:
我查了下,微信讀書(shū)上居然沒(méi)有一本完整的書(shū)來(lái)講它。很可惜。但有兩本書(shū),講到了 SonarQube 平臺(tái),他們分別是《Jenkins 2權(quán)威指南》和《Jenkins 2.x實(shí)踐指南》
作為持續(xù)集成必知的組件,我覺(jué)得這部分知識(shí),不可或缺。
像上面這種 bug 要由人工查,很容易漏掉!
等等,今天不是 2月12號(hào)嗎,農(nóng)歷大年初一。
你要問(wèn)我,大年初一為什么還在發(fā)技術(shù)文,那我就來(lái)說(shuō)點(diǎn)花絮。權(quán)當(dāng)給大家伙兒新年一點(diǎn)樂(lè)子。
本來(lái)前一周已經(jīng)在寫(xiě)一篇大數(shù)據(jù)治理長(zhǎng)文,參考了很多論文,博客還有書(shū)籍。透露下內(nèi)容也沒(méi)關(guān)系,畢竟咱是小臺(tái),不怕抄襲。但,寫(xiě)著寫(xiě)著,內(nèi)容突然寫(xiě)海了,失控了。我的天,我完全不知道該怎么剎住閘。
但這個(gè)時(shí)候,偏偏沖進(jìn)來(lái)這么個(gè)有趣的bug. 我想大部分讀者會(huì)踩到這個(gè)坑,所以我就先寫(xiě)這篇 Not IN.
但,我得自己搭環(huán)境啊,沒(méi)有親自實(shí)現(xiàn)過(guò)的東西,我從來(lái)都不亂講的。
于是模擬公司的一整套開(kāi)發(fā)流程,從 JIRA, Bitbucket, 一路拐到 Jenkins, SonarQube, Github, 試了 n 多配置環(huán)境,云上,本地,最后好不容易湊到一塊兒,發(fā)現(xiàn) SonarQube 支持 SQL 審查,需要 GPL License.
完了!
缺了那種在自己的計(jì)算機(jī)實(shí)驗(yàn)室打造出來(lái)的環(huán)境,怎么著,都差點(diǎn)意思。但是呢,文章一路記錄下來(lái),總不能不發(fā)吧。
哎,硬著頭發(fā),咬著牙,發(fā)吧。
朋友們,《有關(guān)SQL》還活著。2021年,我們齊頭并進(jìn),大步子邁向人生巔峰!
嗯,大過(guò)年的,誰(shuí)家不喝點(diǎn)雞湯啊
往期精彩:
我在面試數(shù)據(jù)庫(kù)工程師候選人時(shí),常問(wèn)的一些題
零基礎(chǔ) SQL 數(shù)據(jù)庫(kù)小白,從入門(mén)到精通的學(xué)習(xí)路線(xiàn)與書(shū)單
