
CnosDB 的 JDBC 驱动(基于 Flight SQL)尚未完全实现 executeUpdate() 的行计数功能,因此即使数据写入成功,executeUpdate() 也恒定返回 -1,这是当前版本的已知限制,而非使用错误。
cnosdb 的 jdbc 驱动(基于 flight sql)尚未完全实现 `executeupdate()` 的行计数功能,因此即使数据写入成功,`executeupdate()` 也恒定返回 -1,这是当前版本的已知限制,而非使用错误。
在使用 CnosDB 的 JDBC 接口进行数据写入时,开发者常遇到一个看似异常的现象:SQL 执行无报错、数据可正常查询(如日志中 SELECT * FROM m2 明确返回 7 行),但 executeUpdate() 方法却始终返回 -1,导致单元测试中 assertEquals(4, rs006) 失败。
这并非数据写入失败,而是 CnosDB 当前 JDBC 实现的语义限制:其底层基于 Apache Arrow Flight SQL 协议,而该协议本身不强制要求服务端返回影响行数(updateCount)。CnosDB 的 Flight SQL 服务端暂未填充或透传该字段,JDBC 驱动因而统一返回 JDBC 规范允许的默认值 -1(表示“操作成功但行数不可用”)。
✅ 正确理解与实践建议:
✅ 无需将
-1视为错误:只要executeUpdate()未抛出SQLException,且后续SELECT可查到数据,即表明写入已成功;✅ 避免依赖返回值做逻辑判断:不要用
if (rowsAffected == 4) { ... }进行业务校验,应改用显式查询验证(如COUNT(*));-
✅ 单元测试适配示例:
// ❌ 错误:断言具体行数(会失败) // assertEquals(4, stmt.executeUpdate(insertSql)); // ✅ 正确:仅断言执行不抛异常,并辅以查询验证 stmt.executeUpdate(insertSql); // 不捕获返回值,或容忍 -1 ResultSet rs = stmt.executeQuery("SELECT COUNT(*) FROM m2"); rs.next(); assertTrue(rs.getLong(1) >= 4); // 确保至少有4行
⚠️ 注意事项:
-
execute()和executeUpdate()在 CnosDB JDBC 中对INSERT语句行为一致(均不返回真实行数),优先使用executeUpdate()语义更清晰; -
CREATE DATABASE/CREATE TABLE等 DDL 语句应继续使用execute(),因其不产生结果集,且返回布尔值符合规范; - 时间戳精度需注意:CnosDB 默认纳秒级,
CAST(... AS TIMESTAMP)输入须为纳秒整数(如1672301798050000000),否则可能被截断或解析异常(如日志中1970-01-01T00:00:00.263356943表明毫秒级输入被当作纳秒处理);
? 总结:-1 是 CnosDB 当前 Flight SQL JDBC 实现的阶段性特征,反映的是协议能力边界,而非功能缺陷。开发者应聚焦于业务数据的最终一致性验证,而非驱动层的元信息返回。随着 CnosDB 对 Flight SQL 标准支持的持续完善,未来版本有望提供准确的 updateCount。

















