Гость
Map
Форумы / Java [игнор отключен] [закрыт для гостей] / Sybase getUpdateCount / 11 сообщений из 11, страница 1 из 1
05.09.2020, 18:12
    #39995921
ivanra
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Sybase getUpdateCount
Столкнулся со странным поведением PreparedStatement.getUpdateCount() в Sybase (ASE).
При выполнении CRUD операций метод возвращает -1, хотя в других базах возвращается реальное число (например, кол-во удаленных записей). Пока что выкручиваюсь с помощью доп.запроса
Код: sql
1.
select @@rowcount


Пробовал оба драйвера (jtds, jconn) - с одинаковым результатом, set nocount on/off также не влияет. Что это может быть? Особенности СУБД или админы какие-то свойства в базе установили? Кто-нибудь сталкивался?
...
Рейтинг: 0 / 0
09.09.2020, 00:03
    #39996743
Dmitry.
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Sybase getUpdateCount
ivanra,

давай кусок кода как используешь getUpdateCount()
...
Рейтинг: 0 / 0
09.09.2020, 08:48
    #39996777
ivanra
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Sybase getUpdateCount
Вопрос больше про Sybase, чем про getUpdateCount. С другими серверами всё работает как надо. Тут ничего интересного, всё стандартно:
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
PreparedStatement ps = ...blablabla;
boolean isResultSet = ps.execute();
if (isResultSet) {
  // запрос вернул данные
  ...
} else {
  // CRUD or no result
  int updateCount = ps.getUpdateCount(); // для Sybase почему-то всегда возвращается -1
  ...
}
...
Рейтинг: 0 / 0
09.09.2020, 13:40
    #39996912
Leonid Kudryavtsev
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Sybase getUpdateCount
Мне кажется, Вы неправильно используете getUpdateCount().

Retrieves the current result as an update count; if the result is a ResultSet object or there are no more results, -1 is returned. This method should be called only once per result.

С Sybase не работал, но http://infocenter.sybase.com/help/index.jsp?topic=/com.sybase.infocenter.dc39001.0707/html/prjdbc0707/BHCBFAAB.htm наводит на мысль, что Sybase альтернативно одаренно на Update / Delete возврашает ResultSet'ы. Т.е. нужно обрабатывать ИЛИ ResultSet'ы ИЛИ вызывать getUpdateCount. IMHO. Не точно.

Что делает Ваш код и зачем такая странно-сложная конструкция нужна, не знаю. Похоже какая-то универсальность, которая криво и некорректно задумана и в результате и работает не так, как ожидалось.
...
Рейтинг: 0 / 0
09.09.2020, 13:46
    #39996914
Leonid Kudryavtsev
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Sybase getUpdateCount
На JavaDoc про execute написано

Returns:
true if the first result is a ResultSet object; false if it is an update count or there are no results

уточнение "the first result" как-то немного вводит в ступор. Я бы поэксперементировал и попытался понять, что для вашей команды DML выдают методы getResultSet / getMoreResults / getUpdateCount.
...
Рейтинг: 0 / 0
09.09.2020, 13:55
    #39996918
Leonid Kudryavtsev
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Sybase getUpdateCount
Я бы еще проверил:
1) это только на PreparedStatement бага или на просто Statement тоже.
2) это только на execute бага или на executeUpdate тоже

В принципе, тип операции SELECT или DML должен быть понятен на фазе prepared. Возможно на фазе execute данные проверки (что возврашает команда), банально не реализованы - т.к. нафиг нормальным людям не надо.

IMHO
...
Рейтинг: 0 / 0
09.09.2020, 15:48
    #39996977
ivanra
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Sybase getUpdateCount
Leonid Kudryavtsev,

Тут действительно есть некая универсальность, поскольку этот код - просто выжимка и результат отладки кода компоненты camel-sql (org.apache.camel.component.sql.SqlProducer.java). Желающие могут увидеть полный код в методе
Код: java
1.
public void process(final Exchange exchange)


И дело тут именно в Sybase, поскольку весь этот код, с тем же самым драйвером jtds работает нормально в MSSQL.
Сам sql в этом очень простой
Код: sql
1.
delete from myTable where id=?


В нормальных условиях getUpdateCount() возвращает либо 0, либо 1. Но в данном случае - всегда -1

Пока пришлось дописать туда второй запрос
Код: sql
1.
2.
delete from myTable where id=?
select @@rowcount


Соответственгно в приведенном java коде теперь попадаем не в else блок, а в блок if (isResultSet) и там получаем ожидаемый результат
...
Рейтинг: 0 / 0
09.09.2020, 17:14
    #39996996
Leonid Kudryavtsev
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Sybase getUpdateCount
Я немного не про это, проверьте, правильно ли возврашает результат

PreparedStatement.executeUpdate
и
PreparedStatement.execute + getUpdateCount

На мой взгляд, скорее всего бага - т.е. надо писать письмо в Sybase

Если executeUpdate работает корректно, то наверное можно сделать свой мини-патч-workaround. Например подменив класс org.apache.camel.component.sql.SqlProducer.java или даже напрямую Sybase'вский PreparedStatement.

IMHO
...
Рейтинг: 0 / 0
09.09.2020, 19:58
    #39997063
ivanra
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Sybase getUpdateCount
Leonid Kudryavtsev,

в executeUpdate то же самое, только еще хуже. В драйвере jtds зачем-то вставлен такой костыль:
Код: java
1.
2.
3.
4.
5.
    public int executeUpdate() throws SQLException {
...
        int res = getUpdateCount();
        return res == -1 ? 0 : res; //WTF???
    }


Тупо меняют эту -1 на 0. Видимо, разработчиков драйвера сервер Sybase тоже в тупик поставил
...
Рейтинг: 0 / 0
10.09.2020, 02:50
    #39997122
Leonid Kudryavtsev
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Sybase getUpdateCount
ivanra,

Мрак какой-то
...
Рейтинг: 0 / 0
12.09.2020, 01:41
    #39997872
Dmitry.
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Sybase getUpdateCount
ivanra,

твой код в принципе верный и должен работать

вот пример полного кода от сайбейз для получения всех резалтсетов:

http://infocenter.sybase.com/help/index.jsp?topic=/com.sybase.help.sqlanywhere.12.0.1/ulj/ulj-api-resultset-int-getrowcount-met.html

я вижу, что это для sybase sqlanywhere, но для ASE тоже подходит.


в executeUpdate() для jtds код верный потому что этот метод не должен возвращать -1 согласно джавадок.

в сайбейз есть параметр сессии: SET NOCOUNT ON
его часто используют в процедурах но забывают вернуть обратно в нормальное положение "OFF"
...
Рейтинг: 0 / 0
Форумы / Java [игнор отключен] [закрыт для гостей] / Sybase getUpdateCount / 11 сообщений из 11, страница 1 из 1
Целевая тема:
Создать новую тему:
Автор:
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]