2009-04-16 52 views
1

我正在使用官方Sybase JDBC驱动程序连接到数据库,并通过创建CallableStatement来调用存储过程,将参数绑定到它并调用.execute()。为什么Sybase JDBC驱动程序“吃”了异常?

然而,我发现没有异常被抛出,即使存储过程失败。我可以通过使用Wireshark嗅探到数据库的流量并观察返回的错误消息来验证失败是否传播回给我。

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

  1. 为什么.execute()和.executeUpdate ()有不同的表现?从接口的Sun文档似乎他们应该做的(几乎)同样的事情...
  2. 是否总是与适当向.executeUpdate替换.execute()()调用存储过程的时候?存储过程是否必须符合某些特定的要求才能使用.executeUpdate()进行调用? (例如,必须将它有一个更新/删除/插入语句作为最后一步?)

更新:我试过JTDS,并正确的行为(如:它会抛出SQLException的两个病例 - 与.execute()和.executeUpdate())。但是,由于我无法控制的限制,切换驱动程序并不是真的可能。

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

+1

其他司机的行为是否相同?那么jTDS呢? http://jtds.sourceforge.net/ – 2009-04-16 06:55:56

回答

5

因为那些Sybase人疯了,这就是为什么它吃例外!没有理由避免使用executeUpdate()来准备/可调用语句。如果这就是你必须使用的工具,然后继续这样做。但是你应该用Sybase提交错误报告 - 驱动程序没有理由这样做。

0

什么都不知道有关Sybase但

executeUpdate的返回比执行更相关信息:插入/更新的行#/删除

- >这是UPDATE INSERT DELETE使用,并根据DML操作到javadoc。

executeQuery返回一个ResultSet,这是用于SELECT语句的。

1

不知道,SYBASE的人是否是“疯狂”。也许。

在另一方面,没有synchronuously检索结果,当你不主动检查的调用语句的返回码可能是有意义的性能代价。我还没有完全测试过,但有一个简单的解决方法来解决你的问题(ASE 15。5,jconn 7):

当您从存储过程(至少调用存储过程时)取一个出PARAM异常会被触发:

// 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); 
    } 

另一种好奇的是,这种行为只显示了当在嵌套存储过程调用中触发错误时,如果最上面的过程引发错误,则不需要解决方法。