记一次Oracle数据库in语句事故
程序员文章站
2022-07-13 08:05:18
...
1、前情介绍
有个数据处理的活比较着急,从同事的代码中拷贝了一段SQL语句,其中,包含如下的语句:
SELECT *
FROM a
WHERE col IN
(SELECT col
FROM b
WHERE b_col=col_val)
这段sql并不难懂,就是返回a表中col的值满足in子句中查询条件的结果。但是,我在实际中遇到的情况是,这个in子句一直不生效,这个语句也不报错。查了半天,最后发现b表没有名为col的列。
2、原因分析
如果b表没有col列时,这个语句就相当于:
SELECT *
FROM a
WHERE 'a' IN
(SELECT 'a'
FROM b
WHERE b_col=col_val)
只要子查询能够查会结果,这个in子句就会返回true。这样,就导致了这个筛选条件实际不生效。而且,并不报错,在实际中特别不好分析。
3、场景复现
为了复现这个场景,这里用如下的表结构和数据:
CREATE TABLE Persons
(
Name varchar(255),
Address varchar(255)
);
INSERT INTO Persons VALUES ('Bill Gates', 'Beijing');
INSERT INTO Persons VALUES ('Kobe Byrant', 'Los Angeles');
CREATE TABLE Citys
(
CityName varchar(255),
ZipCode varchar(255)
);
INSERT INTO Citys VALUES ('Beijing', '010');
当执行如下查询:
SELECT *
FROM persons
WHERE Name IN
(SELECT Name
FROM citys
WHERE zipCode='010')
得到结果:
NAME | ADDRESS |
---|---|
Bill Gates | Beijing |
Kobe Byrant | Los Angeles |
而在执行如下查询时,查不到结果:
SELECT *
FROM persons
WHERE Name IN
(SELECT Name
FROM citys
WHERE zipCode='251718')
4、写在最后
这种问题,在学校那会儿,肯定有一大堆语料强调过。然而,这种问题,不结结实实被坑一次,应该不会长记性。
接下来,推荐两个SQL在线测试的网站:
- Oracle Live SQL:http://livesql.oracle.com,需要注册登录,有时候比较慢。
- Sqlfiddle:http://sqlfiddle.com。不需要注册,即时建表插数,非常方便。