为什么Sybase JDBC驱动程序“吃掉”异常?

时间:2009-04-16 06:49:21

标签: java jdbc sybase sqlexception

我正在使用官方的Sybase JDBC驱动程序连接到数据库并通过创建CallableStatement调用存储过程,将参数绑定到它并在其上调用.execute()。

但是,我发现即使存储过程失败,也不会抛出任何异常。我可以通过使用Wireshark嗅探数据流并查看返回的错误消息来验证故障是否传播回给我。

最后我发现使用.executeUpdate()而不是.execute()确实给了我例外,但我还有两个问题:

  1. 为什么.execute()和.executeUpdate()表现不同?从接口的SUN文档看来,它们应该(几乎)做同样的事情......
  2. 在调用存储过程时,用.executeUpdate()替换.execute()是否总是合适的?存储过程是否必须符合某些特定要求才能使用.executeUpdate()进行调用? (例如,它必须有更新/删除/插入语句作为最后一步吗?)
  3. 更新:我尝试过jTDS,它的行为正确(如:在两种情况下都抛出SQLException - 使用.execute()和.executeUpdate())。但是,由于我无法控制的限制,切换驱动程序实际上是不可能的。

    另外:我对此存储过程返回的结果不感兴趣,它是一个插入/更新类型过程。我只会被插入以查看(并且能够捕获/记录)它是否失败。我尝试过的另一件事是在.execute()之后从连接中获取警告,但它也没有包含任何内容。

3 个答案:

答案 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语句。