我正在使用官方的Sybase JDBC驱动程序连接到数据库并通过创建CallableStatement调用存储过程,将参数绑定到它并在其上调用.execute()。
但是,我发现即使存储过程失败,也不会抛出任何异常。我可以通过使用Wireshark嗅探数据流并查看返回的错误消息来验证故障是否传播回给我。
最后我发现使用.executeUpdate()而不是.execute()确实给了我例外,但我还有两个问题:
更新:我尝试过jTDS,它的行为正确(如:在两种情况下都抛出SQLException - 使用.execute()和.executeUpdate())。但是,由于我无法控制的限制,切换驱动程序实际上是不可能的。
另外:我对此存储过程返回的结果不感兴趣,它是一个插入/更新类型过程。我只会被插入以查看(并且能够捕获/记录)它是否失败。我尝试过的另一件事是在.execute()之后从连接中获取警告,但它也没有包含任何内容。
答案 0 :(得分:5)
因为那些Sybase人很疯狂,所以这就是为什么它会吃Exceptions!没有理由避免对准备/可调用语句使用executeUpdate()。如果这是你必须使用它来使它工作,那么继续这样做。但您应该向Sybase提交错误报告 - 驱动程序没有理由这样做。
答案 1 :(得分:1)
不确定,sybase人是否“疯狂”。也许
另一方面,当您不主动检查可调用语句的返回代码时,不同步检索结果可能在性能方面有意义。我还没有完全测试它,但是你的问题有一个简单的解决方法(ASE 15.5,jconn 7):
从存储过程中获取out参数时会触发异常(至少在调用存储过程时):
// one may force the error check by retrieving the return code!
cs = conn.prepareCall("{ ? = call sp_nested_error @nNestLevels = 1 }");
cs.registerOutParameter(1, Types.INTEGER);
cs.execute();
try {
cs.getInt(1);
fail();
} catch(SQLException e) {
assertTrue(e.getMessage().indexOf("some error") > -1);
}
另一个好奇心是,只有在嵌套存储过程调用中触发错误时才会显示此行为,并且当最顶层的过程引发错误时,不需要解决方法。
答案 2 :(得分:0)
对Sybase没有任何了解,但
executeUpdate返回的信息多于执行:插入/更新/删除的行数
- >它可用于UPDATE INSERT DELETE,以及根据javadoc的DML操作。
executeQuery返回一个ResultSet,这是用于SELECT语句。