Почему драйвер Sybase JDBC использует исключения?

Я использую официальный драйвер Sybase JDBC для подключения к базе данных и вызова хранимой процедуры путем создания CallableStatement, привязки к нему параметров и вызова для него .execute().

Однако я обнаружил, что никаких исключений не возникает, даже если хранимая процедура завершается ошибкой. Я могу убедиться, что сбой передается мне, анализируя трафик к базе данных с помощью Wireshark и наблюдая за возвращающимися сообщениями об ошибках.

Наконец, я обнаружил, что использование .executeUpdate() вместо .execute() действительно дает мне исключения, однако у меня осталось два вопроса:

  1. Почему .execute() и .executeUpdate() ведут себя по-разному? Из документации SUN по интерфейсу кажется, что они должны делать (почти) одно и то же...
  2. Всегда ли уместно заменить .execute() на .executeUpdate() при вызове хранимой процедуры? Должна ли хранимая процедура соответствовать некоторым конкретным требованиям, чтобы ее можно было вызывать с помощью .executeUpdate()? (например, должен ли он иметь оператор обновления/удаления/вставки в качестве последнего шага?)

Обновление: я попробовал jTDS, и он ведет себя корректно (например, выдает SQLException в обоих случаях — с .execute() и с .executeUpdate()). Однако из-за ограничений, не зависящих от меня, переключение драйвера на самом деле невозможно.

Кроме того: меня не интересует результат, возвращаемый этой хранимой процедурой, это процедура типа вставки/обновления. Мне бы только вставить посмотреть (и суметь отловить/логировать) сбой или нет. Еще одна вещь, которую я пробовал, - это отключить предупреждения от соединения после .execute(), но оно также ничего не содержало.


person Grey Panther    schedule 16.04.2009    source источник
comment
другие водители ведут себя так же? А как насчет JTDS? jtds.sourceforge.net   -  person Tim Büthe    schedule 16.04.2009


Ответы (3)


Потому что эти люди из Sybase сумасшедшие, вот почему они съедают исключения! Нет причин избегать использования executeUpdate() для подготовленных/вызываемых операторов. Если это то, что вам нужно использовать, чтобы заставить его работать, тогда вперед и сделайте это. Но вы должны подать отчет об ошибке в Sybase - нет причин, по которым драйвер должен это делать.

person Adam Hawkes    schedule 20.04.2009

не уверен, что люди на sybase "сумасшедшие". Может быть.

С другой стороны, не синхронное извлечение результатов, когда вы не проверяете код возврата вызываемого оператора, может иметь смысл с точки зрения производительности. Я еще не тестировал его полностью, но есть простой обходной путь для вашей проблемы (ASE 15.5, jconn 7):

исключение будет вызвано, когда вы получите параметр вывода из хранимой процедуры (по крайней мере, при вызове хранимых процедур):

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

Еще одно любопытство заключается в том, что это поведение проявляется только тогда, когда ошибки инициируются в вызовах вложенных хранимых процедур, и обходной путь не требуется, когда самая верхняя процедура вызывает ошибку.

person user1050755    schedule 06.08.2012

ничего не знаю о Sybase, но

executeUpdate возвращает больше информации, чем execute: количество вставленных/обновленных/удаленных строк.

-> его можно использовать с операциями UPDATE INSERT DELETE и DML в соответствии с javadoc.

executeQuery возвращает ResultSet, это для операторов SELECT.

person chburd    schedule 16.04.2009