结合 Mybatis,探讨 Oracle 中 in 与 not in 的陷阱

简介: 一、Oracle 中的 in 与 not in1. 正常情况下的使用查询语句使用 in 和 not in 的例子--表:T_USER,USER_ID 有 1,2,3,4,5,6--查询 userId 中包含1,2,3的数据--查询结果:1,2,3SELECT * FROM T_USER T WHERE T.

一、Oracle 中的 in 与 not in

1. 正常情况下的使用

查询语句使用 in 和 not in 的例子

--表:T_USER,USER_ID 有 1,2,3,4,5,6
--查询 userId 中包含1,2,3的数据
--查询结果:1,2,3
SELECT * FROM T_USER T WHERE T.USER_ID IN (1, 2, 3);

--查询 userId 中不包含1,2,3的数据
--查询结果:4,5,6
SELECT * FROM T_USER T WHERE T.USER_ID NOT IN (1, 2, 3);

2. 数据为空时的使用

数据为空时,是最容易产生理解错误和查询报错。

数据为“空”表现为,没有数据或者数据为 null 。如以下两种情景:

  • 数据为空,例如
SELECT * FROM T_USER T WHERE T.USER_ID IN ();

这时候查询语句会报错,“缺失表达式”。

  • 数据为 null,例如
SELECT * FROM T_USER T WHERE T.USER_ID IN (NULL);

这时候查询结果为空,即没有任何数据。

而此种情况下容易产生理解错误的是以下两个查询语句:

SELECT * FROM T_USER T WHERE T.USER_ID IN (NULL);

SELECT * FROM T_USER T WHERE T.USER_ID NOT IN (NULL);

很多人以为这两个查询语句的查询结果应该是相反的,即 IN (NULL) 查不出数据,而 NOT IN (NULL) 查出所有数据,或者反过来。

但实际的查询结果是,两个语句查询结果都为空,即都没有数据。

二、结合 Mybatis,探讨 Oracle 中 in 与 not in 的陷阱

1. 常用场景:

在 Mybatis 中使用 in 或者 not in 的方式如下:

<if test="null != list and list.size > 0 ">
    AND T.USER_ID IN
    <foreach collection="list" item="userID" open="(" separator="," close=")">
        #{userID}
    </foreach>
</if>

这种方式可以有效避免因为出现 IN ( ) 而导致的缺失表达式异常。

但是这个表达式所使用的场景是,有 userID 集合时,查询出集合中 userID 数据;没有 userID 集合时,查询出所有 userID 的数据。

2. 特殊场景:当没有 userID 集合时,不查任何数据

偶尔会出现这样的使用场景,当没有 userID 集合时,不查任何数据。

这时候就有人会把 if 条件去掉,即采用如下的查询方式

AND T.USER_ID IN
<foreach collection="list" item="userID" open="(" separator="," close=")">
    #{userID}
</foreach>

很容易理解为什么有人会这么写。list 有值时,in 就有数据,查询也就有数据;list 为空时,in 就没有数据,查询也就得不到数据。

理想很丰富,现实很骨感。

如果你这么写的时候,你们当list为空时,就会出现如下的查询语句

AND T.USER_ID IN

直接导致缺失表达式异常。

我的一个解决办法是,在 list 中增加一个数据库中没有的 userID,例如 userID = 0 的数据

那么当你需要的 list 为空时,list 中仍然保留有 0 这个值。于是,当你查询时会出现如下语句

AND T.USER_ID IN (0)
相关文章
|
8月前
|
Oracle Java 数据库连接
使用Mybatis generator自动生成代码,仅限Oracle数据库
使用Mybatis generator自动生成代码,仅限Oracle数据库
|
6月前
|
Oracle 关系型数据库 Java
mybatis使用statement.getGenreatedKeys(); useGeneratedKeys=”true”;使用自增主键获取主键值策略和Oracle不支持自增,Oracle使用序列
mybatis使用statement.getGenreatedKeys(); useGeneratedKeys=”true”;使用自增主键获取主键值策略和Oracle不支持自增,Oracle使用序列
|
8月前
|
SQL Oracle 关系型数据库
整合Mybatis-Plus高级,Oracle 主键Sequence,Sql 注入器实现自定义全局操作
整合Mybatis-Plus高级,Oracle 主键Sequence,Sql 注入器实现自定义全局操作
173 0
|
8月前
mybatis-plus使用oceanbase-oracle模式
mybatis-plus使用oceanbase-oracle模式
567 2
|
8月前
|
Oracle Java 关系型数据库
SpringBoot整合Mybatis连接Oracle数据库
SpringBoot整合Mybatis连接Oracle数据库
SpringBoot整合Mybatis连接Oracle数据库
|
Oracle 关系型数据库 Java
Mybatis JdbcType与Oracle、MySql数据类型对应列表
Mybatis JdbcType与Oracle、MySql数据类型对应列表
266 0
|
XML SQL Oracle
使用mybatis 连接Oracle 数据库 xml 文件中需要注意的问题
使用mybatis 连接Oracle 数据库 xml 文件中需要注意的问题
201 0
|
3月前
|
存储 Oracle 关系型数据库
Oracle数据库的应用场景有哪些?
【10月更文挑战第15天】Oracle数据库的应用场景有哪些?
245 64
|
1月前
|
存储 Oracle 关系型数据库
数据库数据恢复—ORACLE常见故障的数据恢复方案
Oracle数据库常见故障表现: 1、ORACLE数据库无法启动或无法正常工作。 2、ORACLE ASM存储破坏。 3、ORACLE数据文件丢失。 4、ORACLE数据文件部分损坏。 5、ORACLE DUMP文件损坏。
115 11
|
2月前
|
Oracle 关系型数据库 数据库
Oracle数据恢复—Oracle数据库文件有坏快损坏的数据恢复案例
一台Oracle数据库打开报错,报错信息: “system01.dbf需要更多的恢复来保持一致性,数据库无法打开”。管理员联系我们数据恢复中心寻求帮助,并提供了Oracle_Home目录的所有文件。用户方要求恢复zxfg用户下的数据。 由于数据库没有备份,无法通过备份去恢复数据库。

推荐镜像

更多