应优先用getErrorCode()获取Oracle专属错误码(如1对应ORA-00001),再辅以getSQLState()(如"23000")做宽泛分类,避免解析getMessage()字符串——因其受国际化、日志截断等影响不可靠。

Oracle异常的SQLState和ErrorCode怎么看
Oracle抛出的异常本质还是SQLException,但关键信息藏在getSQLState()和getErrorCode()里,不是靠getMessage()字符串匹配。比如唯一约束冲突,getErrorCode()通常是1(ORA-00001),而getSQLState()是"23000"——这是SQL标准码,比Oracle原错误号更稳定。
实操建议:
- 优先用
getErrorCode()判断具体Oracle错误,它直接对应ORA-xxxxx编号,查文档最准 -
getSQLState()适合做宽泛分类,比如"23000"涵盖所有完整性约束违规 - 避免用
getMessage().contains("ORA-00001"),因为不同语言环境或驱动版本可能改变提示文本
用Spring JDBC怎么优雅提取Oracle错误码
Spring的SQLExceptionTranslator默认不暴露原始错误码,得绕一层。最直接的方式是在catch (DataAccessException e)里向下转型回SQLException。
实操建议:
- 用
ExceptionUtils.getRootCause(e)拿到最底层异常,再强转为SQLException - 检查是否为
org.springframework.dao.DuplicateKeyException,它内部已映射了1号错误,但自定义约束名时仍需读getErrorCode() - 别依赖
JdbcSqlExceptionTranslator的translate()结果,它把细节吞掉了
ORA-01403(NO_DATA_FOUND)在JDBC里为什么捕不到
Oracle的NO_DATA_FOUND(ORA-01403)在JDBC中**不会抛出异常**,而是返回空结果集。这是Oracle驱动的主动压制行为,和PL/SQL里逻辑完全不同。
实操建议:
- 执行
SELECT ... INTO类语句时,必须手动检查ResultSet.next()返回false - 用
CallableStatement调存储过程时,若过程内RAISE NO_DATA_FOUND,JDBC才会收到SQLException且getErrorCode()为100 - 别指望在DAO层统一拦截“没数据”异常,这事得在业务逻辑里显式处理
自定义Oracle异常解析工具类要注意什么
写一个OracleExceptionUtils解析错误时,最容易错的是把getErrorCode()当成纯数字处理——它其实是驱动返回的int,但某些旧版ojdbc(如ojdbc6)对警告会返回负值,而ORA-错误号全是正数。
实操建议:
- 只对
getErrorCode() > 0的情况做ORA-映射,负值留给SQLWarning或驱动内部状态 - 缓存常用错误码判断逻辑,比如
isDuplicateKey(int code)直接return code == 1,别每次都if-else - 测试时务必用真实Oracle数据库跑,H2或HSQLB模拟的ORA-错误码不一致
Oracle异常解析真正的复杂点不在代码怎么写,而在错误码含义随Oracle版本、字符集、甚至NLS设置浮动。比如ORA-00942在有些场景下可能是权限问题,也可能是对象名大小写不匹配——得结合getSQLState()、错误上下文、甚至数据库日志交叉验证。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











