代码之家  ›  专栏  ›  技术社区  ›  Grey Panther

为什么SybaseJDBC驱动程序“吃”了例外?

  •  1
  • Grey Panther  · 技术社区  · 15 年前

    我正在使用正式的SybaseJDBC驱动程序连接到数据库,并通过创建CallableStatement、将参数绑定到它并对它调用.execute()来调用存储过程。

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

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

    1. 为什么.execute()和.executeUpdate()的行为不同?从界面的Sun文档来看,他们应该(几乎)做同样的事情…
    2. 调用存储过程时,是否总是将.execute()替换为.executeUpdate()?存储过程必须符合某些特定要求才能使用.executeUpdate()调用吗?(例如,作为最后一步,它必须具有update/delete/insert语句吗?)

    更新 :我尝试过JTD,它的行为是正确的(如:它在这两种情况下都抛出了sqlException-with.execute()和with.executeUpdate())。然而,由于我无法控制的约束,关闭驱动程序是不可能的。

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

    3 回复  |  直到 12 年前
        1
  •  5
  •   No AI now No AI ever    15 年前

    因为那些Sybase的人都疯了,所以它才会吃例外!没有理由避免对准备好的/可调用的语句使用executeUpdate()。如果这就是你要用的方法,那就去做吧。但是你应该向Sybase提交一个bug报告——驱动程序没有理由这么做。

        2
  •  1
  •   user1050755    12 年前

    不确定,Sybase的人是否“疯了”。也许吧。

    另一方面,如果不主动检查可调用语句的返回代码,则不同步地检索结果可能有助于提高性能。我还没有完全测试过它,但是对于您的问题有一个简单的解决方法(ASE15.5,JCONN7):

    从存储过程中提取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);
        }
    

    另一个好奇心是,这种行为只在嵌套存储过程调用中触发错误时才会出现,而当最顶层的过程引发错误时,不需要解决方法。

        3
  •  0
  •   chburd    15 年前

    对Sybase一无所知,但

    ExecuteUpdate返回的信息多于Execute:插入/更新/删除的行数

    ->根据javadoc,它可以用于更新、插入、删除和DML操作。

    ExecuteQuery返回一个结果集,这是用于select语句的。