Как можно обрабатывать NULL и обычные значения без использования разных подготовленных операторов? - PullRequest
6 голосов
/ 12 сентября 2011

Рассмотрим этот простой метод:

public ResultSet getByOwnerId(final Connection connection, final Integer id) throws SQLException {
    PreparedStatement statement = connection.prepareStatement("SELECT * FROM MyTable WHERE MyColumn = ?");
    statement.setObject(1, id);
    return statement.executeQuery();
}

Предполагается, что пример метода должен выбирать все из некоторой таблицы, где совпадает значение столбца, что должно быть простым.Ужасная деталь в том, что передача NULL для идентификатора приведет к пустому ResultSet, независимо от того, сколько строк в БД, потому что SQL определяет NULL как не euqaling anyting, даже NULL.Единственный способ выбрать те строки, о которых я знаю, - это использовать другое предложение where:

SELECT * FROM MyTable WHERE MyColumn IS NULL

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

Это очень уродливо, и когда у вас есть более одного столбца, который можно обнулять, он может очень быстро запутаться.Как можно обрабатывать NULL и нормальные значения с одним и тем же путем / оператором кода?

Ответы [ 2 ]

2 голосов
/ 12 сентября 2011

Я не пробовал этого, но способ отправить нули в readyStatements - использовать параметр setNull ()

   PreparedStatement statement = connection.prepareStatement("SELECT * FROM MyTable WHERE MyColumn = ?");
    if ( id == null)
       statement.setNull(1, java.sql.Types.INTEGER);
    else    
      statement.setObject(1, id);
    return statement.executeQuery();

РЕДАКТИРОВАТЬ : Спасибо за ответы @Gabe и @Vache. Не похоже, что есть простой способ сделать это, кроме как использовать более сложный подход для динамического создания подготовленного отчета.

Как-то так должно работать -

String sql = " SELECT * FROM MyTable WHERE " + (id==null)?"MyColumn is null":"MyColumn = ?" ;
       PreparedStatement statement = connection.prepareStatement(sql);
        if ( id != null)
          statement.setObject(1, id);
        return statement.executeQuery();
0 голосов
/ 12 сентября 2011

Вы можете использовать такой запрос:

select * from MyTable where 
  case when ?1 is null then MyColumn is null else MyColumn = ?1

Но он повторно использует тот же параметр, поэтому я не знаю, был ли предложенный мной синтаксис (? 1)будет работать.

...