sqlwarning不会中断执行且需主动获取,connection、statement(含子类)、resultset三类对象支持getwarnings();须循环getnextwarning()遍历警告链并调用clearwarnings()清理,否则重复返回。

Java JDBC 中的 SQLWarning 不会中断程序执行,也不会自动打印或抛出,必须主动调用对应对象的 getWarnings() 方法获取,否则就完全“静默丢失”。
哪些对象能报告 SQLWarning
不是所有 JDBC 对象都支持警告,但以下三类明确提供 getWarnings() 方法:
-
Connection:连接建立、事务操作(如
commit()或rollback())时可能产生警告 -
Statement(含
PreparedStatement、CallableStatement):执行 SQL 语句后可检查警告 -
ResultSet:读取数据过程中发生截断(
DataTruncation)、空值处理等可能触发警告
如何正确获取并遍历警告链
每个对象最多只返回第一个警告,而警告本身是链式结构(getNextWarning()),需循环遍历:
错误写法:System.out.println(stmt.getWarnings().getMessage()); —— 可能 NPE,且只取第一个
Java开发手册规约集合,基于阿里巴巴Java开发手册(嵩山版)。 涵盖7大维度:编程规约、异常日志、单元测试、安全规约、MySQL数据库、工程结构、设计规约。 当用户需要:(1) 编写或审查Java代码 (2) 检查命名/代码规范 (3) 处理异常和日志 (4) 编写单元测试 (5) 安全编码 (6) 数据库设...
推荐写法:
SQLWarning warning = stmt.getWarnings();
while (warning != null) {
logger.warn("SQL Warning: {} | SQLState: {} | Code: {}",
warning.getMessage(),
warning.getSQLState(),
warning.getErrorCode());
warning = warning.getNextWarning();
}
stmt.clearWarnings(); // 清空已处理警告,避免重复消费
注意:clearWarnings() 必须显式调用,否则下次再调用 getWarnings() 还会返回相同警告。
关键细节与常见误区
-
不能用 try-catch 捕获:SQLWarning 不是异常,不继承
Throwable,SQLException的 catch 块对它完全无效 -
不是所有驱动都支持:例如部分轻量级 RowSet 实现(如 CachedRowSet)可能始终返回
null,需实测验证 -
SQLState 比 message 更重要:不同数据库对同一类问题(如字段截断)返回的 SQLState 有标准码(如
01004表示被截断的 NULL 值),比中文 message 更利于自动化识别和监控 -
复用对象时务必清理:在连接池或 Statement 复用场景下,若不调用
clearWarnings(),旧警告可能污染后续操作日志
典型警告场景举例
这些情况不会报错,但会生成 SQLWarning:
- 执行
INSERT INTO t(col) VALUES ('too long string'),而col是VARCHAR(5)→ 触发DataTruncation警告 - 调用
resultSet.getString("nullable_col")读取 NULL 值 → 可能返回SQLWarning(取决于驱动实现) - 设置
connection.setTransactionIsolation(Connection.TRANSACTION_REPEATABLE_READ),但数据库实际只支持READ_COMMITTED→ 返回降级警告
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










