JdbcTemplate queryForObject带参数查询Oracle CHAR列触发EmptyResultDataAccessException报错
报错根本原因分析
该问题的核心是Oracle CHAR定长字符类型的存储特性、不同类型比较规则和JDBC预编译参数的默认类型不匹配共同导致的,具体逻辑如下:
- 首先Oracle的
CHAR(n)是定长存储的字符类型,当存入的字符长度小于定义的长度n时,会自动在字符右侧补空格填充到n位。你案例中的SOME_PROP字段定义为CHAR(4),存入'00'时,数据库实际存储的内容是'00 '(末尾补2个空格,总长度为4)。 - 硬编码SQL可以查到结果的原因:Oracle对
CHAR类型和字符串字面量做等值比较时,会自动采用空白填充比较规则,会将较短的字符串补空格到和较长的字符串长度一致后再比较,因此'00'会被自动补为'00 ',和数据库存储的内容匹配,所以能返回正确结果。 - 预编译参数传参查询失败的原因:JDBC默认会将字符串类型的预编译参数识别为
VARCHAR类型,Oracle对CHAR类型和VARCHAR类型做等值比较时,采用的是非空白填充比较规则,不会自动补空格,直接按实际字符逐位对比。数据库存储的'00 '长度为4,传入的参数'00'长度为2,对比结果不相等,因此匹配不到任何记录,就抛出了org.springframework.dao.EmptyResultDataAccessException异常。
内容的提问来源于stack exchange,提问作者CostaVi
相关产品推荐
相关产品推荐

