卧槽!我一个 SQL 老 Boy 竟然栽在 Not IN 上
点击蓝色“有关SQL”关注我哟
加个“星标”,天天与10000人一起快乐成长
图 | Lenis
是的,大年三十,我踩中一个 Bug.
平时风平浪静,今天给我找茬。这一天是什么日子?
全中国14亿人,都在等着这一天。父亲大人,母亲大人,老婆大人,满堂老少齐集一屋,都在等着我发红包,连邻居家牙没长齐的娃儿,都在门口笑着,等我的糖吃。
现在居然出现了一个Bug!
箭矢般的归心,嗷嗷叫的告警,就像 2 个大巴掌,左手一记勾拳,右手一记销魂掌。打得我就像紫霞仙子与牛魔王飞进了肚子,表面冷静无比,肚里翻江倒海。
按照往年的规律,年前最后一天不发代码。不做事,哪来错。以这样的物理措施,保障了新年的祥和,一年又一年。
但今年特殊,原地过年,想着年前把事做完整。结果上午贪心小朋友找我聊聊天,洗了个脑,不自觉的又加了几百行代码。
可,偏偏,心里怕啥,就来啥。下午就爆Bug.
好了,不给自己的错误,找借口。这个 SQL Bug 其实也不高深。举个简单的例子,就像下面这样:
SELECT *
FROM dbo.Products
WHERE Brand NOT IN (
SELECT Brand
FROM dbo.Products
WHERE NAME = 'Transformer'
)
这段 SQL 的目的,是从玩具产品中,查找不是 Transformer 品牌商的玩具。
本来是自信满满,写完提交,毫无悬念。但 QA 硬生生打回来了。
附上的评语,口气异常轻蔑:
你居然让我找到如此简单的 bug,毫无成就感
嗯,好吧。我承认!栽了……
表面上看着一点错没有,逻辑清晰,语法正确通顺,那为什么会错了呢?
原因是这样的:
SELECT Brand
FROM dbo.Products
WHERE NAME LIKE 'Transformer%'
在子查询中,如果不做 Brand 的约束,它有机会是 NULL 值。子查询返回 NULL 值,则无果。
以我做了3年多老测试的角度看,QA绝不能发现这么奇怪的Bug. 于是我好奇打听,他们怎么测的,才发现,原来他们有神器。
这,就是 SonarQube. 本文真正的主角。
之前我也写过,要注意对 SQL 运行的“事后”做监控,提高数据库运行“三高”:高可用,高稳定,高性能。
但,没有涉及到 SQL “事前”审核。经某知友(知乎网友)提醒,SQL 审核最好做在部署代码前。
这款 SonarQube 代码审核平台,正好可以满足需求。它支持 T-SQL, PL/SQL 等常用 SQL 方言。当然,其他近 30 种编程语言,Java,C#, Python, C/C++等,都是支持的。
SonarQube 真正折服我的,是全自动代码测试。它能找到隐藏的Bug,安全漏洞,测试覆盖率,怪味道代码,还有代码复用场景,甚至能精确到某几个存储过程的代码行。
如果有这样的自动化查错机器,你还怕别人说你的代码烂么:
我查了下,微信读书上居然没有一本完整的书来讲它。很可惜。但有两本书,讲到了 SonarQube 平台,他们分别是《Jenkins 2权威指南》和《Jenkins 2.x实践指南》
作为持续集成必知的组件,我觉得这部分知识,不可或缺。
像上面这种 bug 要由人工查,很容易漏掉!
等等,今天不是 2月12号吗,农历大年初一。
你要问我,大年初一为什么还在发技术文,那我就来说点花絮。权当给大家伙儿新年一点乐子。
本来前一周已经在写一篇大数据治理长文,参考了很多论文,博客还有书籍。透露下内容也没关系,毕竟咱是小台,不怕抄袭。但,写着写着,内容突然写海了,失控了。我的天,我完全不知道该怎么刹住闸。
但这个时候,偏偏冲进来这么个有趣的bug. 我想大部分读者会踩到这个坑,所以我就先写这篇 Not IN.
但,我得自己搭环境啊,没有亲自实现过的东西,我从来都不乱讲的。
于是模拟公司的一整套开发流程,从 JIRA, Bitbucket, 一路拐到 Jenkins, SonarQube, Github, 试了 n 多配置环境,云上,本地,最后好不容易凑到一块儿,发现 SonarQube 支持 SQL 审查,需要 GPL License.
完了!
缺了那种在自己的计算机实验室打造出来的环境,怎么着,都差点意思。但是呢,文章一路记录下来,总不能不发吧。
哎,硬着头发,咬着牙,发吧。
朋友们,《有关SQL》还活着。2021年,我们齐头并进,大步子迈向人生巅峰!
嗯,大过年的,谁家不喝点鸡汤啊
往期精彩: