Как узнать количество строк, измененных от выполнения JDBC

Я не уверен, как получить количество строк, затронутых выполнением SQL.

Я делаю так:

boolean isResultSet = statement.execute(arbitrarySQLCommand);

и я могу получить количество строк, затронутых getUpdateCount() метод. Это все хорошо. У меня проблема, когда счетчик обновлений равен нулю. Это может означать:

  1. Это был оператор DML, но он не влиял ни на какие строки. Нулевые строки затронуты - это правильный ответ. Я просто имею в виду, что какое-то условие не было выполнено.

  2. Это был оператор не-DML (скорее всего, оператор DDL), который по определению не изменяет строки, поэтому счетчик обновлений всегда равен нулю (дух!). Или, другими словами: концепция количества обновлений не имеет смысла для таких утверждений.

Что я хотел бы, так это уметь различать ситуацию 1 и 2 выше. Как?

Меня не интересуют операторы, которые производят вывод, поэтому я мог бы также использовать executeUpdate(), но, как я вижу, возвращаемое значение из этого метода имеет тот же недостаток:

Возвращает:

либо (1) количество строк для операторов языка данных SQL (DML), либо (2) 0 для операторов SQL, которые ничего не возвращают

Arghhh!
Я бы хотел, чтобы это было:

Возвращает:

либо (1) количество строк для операторов языка данных SQL (DML), либо (2) -1 для операторов SQL, которые ничего не возвращают



(примечание: я не знаю содержания arbitrarySQLCommand заранее)



Окончательно выбранное решение

Похоже, что JDBC-подобного решения проблемы не существует. На мой взгляд, дизайнеры JDBC допустили серьезную ошибку в getUpdateCount используя значение 0 (ноль) для обозначения оператора, который (по определению) не влияет на строки, поскольку затронутый ноль строк также является абсолютно допустимым значением для результата оператора DML.

Кажется, что единственное возможное решение состоит в том, чтобы выполнить какое-либо сопоставление с шаблоном в операторе SQL, чтобы выяснить, является ли это оператором DML (INSERT,UPDATE,DELETE) или оператором SQL другого типа. Что-то вроде этого:

  1. Извлечь первое слово из arbitrarySQLCommand, Слово оканчивается пробелом или символом EOL.
  2. Если это слово (без учета регистра) имеет значение INSERT, UPDATE или DELETE, то это оператор DML и вывод из getUpdateCount() актуально, в противном случае вывод getUpdateCount() не имеет значения.

Гадкий и подверженный ошибкам. Но единственно возможное решение, которое вышло из этого ТАКОГО вопроса.:-(

2 ответа

Решение

Лучшее, что вы можете сделать, это проверить оператор SQL

Set<String> dmlCommands = new HashSet<String>() {
  {
    add("UPDATE"); add("INSERT"); add("DELETE"); //Add more DML commands ....
  }
};
int updateCount = statement.getUpdateCount();
for(String dml : dmlCommands) {
    if(arbitrarySQLCommand.toUpperCase().contains(dml) && updateCount == 0) {
        updateCount = -1;
        break;
    }
}

Возможно, мой ответ не поможет вам с тем, что вы спросили, но я попал сюда, когда искал, как получить количество строк, на которое влияют, после запуска DML, а не числа строк - с MySQL. И я пишу здесь, что я нашел, чтобы помочь другим.

Моя проблема заключалась в том, что когда я запускаю инструкцию, которая не вносит никаких изменений в таблицу, например

UPDATE table SET field=1 WHERE field=1

метод Statement.executeUpdate(...) возвращает количество найденных строк, а не количество измененных / затронутых строк. Поэтому я не мог сказать, изменил ли запрос что-то в таблице.

Чтобы изменить это, опция должна быть предоставлена ​​в URL при создании соединения (с DriverManager.getConnection()), как это:

jdbc:mysql://${jdbc.host}/${jdbc.db}?useAffectedRows=true

Я нашел это здесь:

http://mybatis-user.963551.n3.nabble.com/Return-number-of-changed-rows-tp3888464p3903155.html

И документация MySQL:

https://dev.mysql.com/doc/connector-j/5.1/en/connector-j-reference-configuration-properties.html

Другие вопросы по тегам