Как установить список параметров для подготовленного оператора?

У меня есть список имен, например:

List<String> names = ...
names.add('charles');
...

и утверждение:

PreparedStatement stmt = 
  conn.prepareStatement('select * from person where name in ( ? )');

как сделать следующее:

stmt.setParameterList(1,names);

Есть ли обходной путь? может кто-нибудь объяснить, почему этот метод отсутствует?

используя: java, postgresql, jdbc3

Ответ 1

Нет никакого чистого способа сделать это, просто установив список в PreparedStatement, о котором я знаю.

Напишите код, который строит инструкцию SQL (или лучше заменяет один или тот же токен) соответствующим количеством меток вопросов (тот же номер, что и в вашем списке), а затем перебирает ваш список, задавая параметр для каждого.

Ответ 2

Этот вопрос очень старый, но никто не предложил использовать setArray

Этот ответ может помочь fooobar.com/questions/5208/...

Ответ 3

Для postgres 9 я использовал этот подход:

 jdbcTemplate.query(getEmployeeReport(), new PreparedStatementSetter() {
        @Override
        public void setValues(PreparedStatement ps) throws SQLException {
            ps.setTimestamp(1, new java.sql.Timestamp(from.getTime()));
            ps.setTimestamp(2, new java.sql.Timestamp(to.getTime()));
            StringBuilder ids = new StringBuilder();
            for (int i = 0; i < branchIds.length; i++) {
                ids.append(branchIds[i]);
                if (i < branchIds.length - 1) {
                    ids.append(",");
                }
            }
            // third param is inside IN clause
            // Use Types.OTHER avoid type check while executing query  
            ps.setObject(3, ids.toString(), **Types.OTHER**);
        }
    }, new PersonalReportMapper());

Ответ 4

этот метод отсутствует из-за стирания типа, тип параметра List теряется во время выполнения. Поэтому необходимо добавить несколько способов: setIntParameters, setLongParameters, setObjectParameters и т.д.

Ответ 5

В случае, если смысл вопроса заключается в установке нескольких параметров в одном вызове...

Поскольку проверка типов уже определена на более высоком уровне, я думаю, что единственная потребность в setObject (...).

Таким образом, можно использовать метод утилиты:

public static void addParams(PreparedStatement preparedStatement, Object... params) throws SQLException {
    for (int i = 0; i < params.length; i++) {
        Object param = params[i];
        preparedStatement.setObject(i+1, param);
    }
}

Использование:

SqlUtils.addParams(preparedStatement, 1, '2', 3d);

Не стесняйтесь преобразовывать это в Java 8 лямбда:)

Ответ 6

Я просматривал код сегодня утром, и у одного из моих коллег был другой подход, просто передайте параметр, используя setString("name1','name2','name3").

Примечание. Я пропустил одиночную кавычку в начале и конце, потому что они будут добавлены setString.

Ответ 7

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

Пример. Предположим, у вас есть список параметров, которые нужно передать в разделе "IN". Просто поместите фиктивную строку внутри предложения "IN", скажем, "PARAM" обозначают список параметров, которые будут появляться на месте этой фиктивной строки.

    select * from TABLE_A where ATTR IN (PARAM);

Вы можете собрать все параметры в одну переменную String в вашем Java-коде. Это можно сделать следующим образом:

    String param1 = "X";
    String param2 = "Y";
    String param1 = param1.append(",").append(param2);

Вы можете добавить все ваши параметры, разделенные запятыми, в одну переменную String, 'param1', в нашем случае.

После сбора всех параметров в одну строку вы можете просто заменить фиктивный текст в вашем запросе, то есть "PARAM" в этом случае, с параметром String, то есть параметром1. Вот что вам нужно сделать:

    String query = query.replaceFirst("PARAM",param1); where we have the value of query as 

    query = "select * from TABLE_A where ATTR IN (PARAM)";

Теперь вы можете выполнить свой запрос с помощью метода executeQuery(). Просто убедитесь, что в вашем запросе нет слова "PARAM". Вы можете использовать комбинацию специальных символов и алфавитов вместо слова "PARAM", чтобы убедиться, что в запросе нет такого слова. Надеюсь, вы получили решение.

Ответ 8

Другой метод:

public void setValues(PreparedStatement ps) throws SQLException {
    // first param inside IN clause with myList values
    ps.setObject(1 , myList.toArray(), 2003); // 2003=array in java.sql.Types
}