Столкнулся со следующей проблемой.
Есть sql-запрос типа
select...
from...
where field in(?)
order by...
так вот, при передаче в качестве второго параметры строки типа "A,B,C" строка парсится и проверяется только вхождение 'A', а наличии 'B' и 'C' игнорируются.
Загвоздка в том что заранее количество параметров для условия IN неизвестно по этому поставить определенное количество ? нельзя.
Может кто сталкивался с такой задачей, подскажите, пожалуйста.
P.S. использую PreparedStatement
Re: Передача параметров в JDBC в условие типа 'in'
Здравствуйте, Аноним, Вы писали:
А>Здравствуйте.
А>Столкнулся со следующей проблемой. А>Есть sql-запрос типа А>select... А>from... А>where field in(?) А>order by... А>так вот, при передаче в качестве второго параметры строки типа "A,B,C" строка парсится и проверяется только вхождение 'A', а наличии 'B' и 'C' игнорируются. А>Загвоздка в том что заранее количество параметров для условия IN неизвестно по этому поставить определенное количество ? нельзя. А>Может кто сталкивался с такой задачей, подскажите, пожалуйста. А>P.S. использую PreparedStatement
В связи с тем, что preparedstatement-ы на уровне БД не дают возможности в in менять количество параметров, то и jdbc это не поддерживает. Нужно генерировать запрос вручную (конечно при этом пропадают преимущества производительности preparedstatement-ов). Ещё есть вариант для упрощения програмирования (проблема со скоростью остаётся) использовать hibernate. В нём можно в условие in передавать сразу коллекцию.
Re: Передача параметров в JDBC в условие типа 'in'
Здравствуйте, Аноним, Вы писали:
А>Может кто сталкивался с такой задачей, подскажите, пожалуйста. А>P.S. использую PreparedStatement
Сталкивались. Подсказываем. Передать множество параметров как один нельзя. В PreparedStatement они биндятся каждый на отдельную метку. Варианты решения.
— Лучше всего подумать над способами как избежать in вообще.
— Можно передавать A,B,C одним параметром, но тогда нужно написать функцию на стороне БД, которая будет парсить и параметры в массив.
— Можно склеивать запрос по количеству параметров непосредственно перед вызовом.
— Можно попробовать тип JDBC Array, но я сильно сомневаюсь что его можно передать в IN. Кроме этого скорее всего придется привязаться к конкретному драйверу.
Re: Передача параметров в JDBC в условие типа 'in'
Здравствуйте, Аноним, Вы писали:
А>Здравствуйте.
А>Столкнулся со следующей проблемой. А>Есть sql-запрос типа А>select... А>from... А>where field in(?) А>order by... А>так вот, при передаче в качестве второго параметры строки типа "A,B,C" строка парсится и проверяется только вхождение 'A', а наличии 'B' и 'C' игнорируются. А>Загвоздка в том что заранее количество параметров для условия IN неизвестно по этому поставить определенное количество ? нельзя. А>Может кто сталкивался с такой задачей, подскажите, пожалуйста. А>P.S. использую PreparedStatement
очень интересная задача, спасибо !
единственное оккультное решение которое приходит в голову — это попытаться использовать вложенный select —
where field in (select * что то там откуда то по какому то условию с внешним параметром)
но опять-таки не знаю или это подойдет в контексте решаемой вами проблемы
Re: Передача параметров в JDBC в условие типа 'in'
Здравствуйте, Аноним, Вы писали:
А>Здравствуйте.
А>Столкнулся со следующей проблемой. А>Есть sql-запрос типа А>select... А>from... А>where field in(?) А>order by... А>так вот, при передаче в качестве второго параметры строки типа "A,B,C" строка парсится и проверяется только вхождение 'A', а наличии 'B' и 'C' игнорируются. А>Загвоздка в том что заранее количество параметров для условия IN неизвестно по этому поставить определенное количество ? нельзя. А>Может кто сталкивался с такой задачей, подскажите, пожалуйста. А>P.S. использую PreparedStatement
Одна из рекомендаций, которые я читал, когда сталкивался с такой задачей, выглядела так:
пусть максимальное количество параметров в in — 10.
select .. from .. where field in (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
и биндим соответсвующие параметры, остаток биндим NULL-ами (или любым другим значением, гарантированно не присутствующим в таблице).
Утверждалось, что БД достаточно умна, чтобы понять, чего мы от неё хотим, и сделать это эффективно.
Мне оказалось проще генерировать SQL-строку динамически. Но и такой подход имеет право на жизнь, особенно если по условию количество условий в in ограничено.
Re: Передача параметров в JDBC в условие типа 'in'
А>Столкнулся со следующей проблемой. А>Есть sql-запрос типа А>select... А>from... А>where field in(?) А>order by... А>так вот, при передаче в качестве второго параметры строки типа "A,B,C" строка парсится и проверяется только вхождение 'A', а наличии 'B' и 'C' игнорируются. А>Загвоздка в том что заранее количество параметров для условия IN неизвестно по этому поставить определенное количество ? нельзя. А>Может кто сталкивался с такой задачей, подскажите, пожалуйста. А>P.S. использую PreparedStatement
Где-то находил аналогичный топик про PostgreSQL, там однозначно говорилось,
что их jdbc такого не поддерживает. Рекомендовали передавать строку значений разделенных запятой
и разбивать в массив её какой-то штатной функцией.
Re: Передача параметров в JDBC в условие типа 'in'
А>Столкнулся со следующей проблемой. А>Загвоздка в том что заранее количество параметров для условия IN неизвестно по этому поставить определенное количество ? нельзя. А>Может кто сталкивался с такой задачей, подскажите, пожалуйста. А>P.S. использую PreparedStatement
очень часто в таком случае советуют загонять данные по которым вы in делаете в TempTable и джойнится с ним
Re[2]: Передача параметров в JDBC в условие типа 'in'
-1 M>Где-то находил аналогичный топик про PostgreSQL, там однозначно говорилось, M>что их jdbc такого не поддерживает. Рекомендовали передавать строку значений разделенных запятой M>и разбивать в массив её какой-то штатной функцией.
Работает и с postgre
PreparedStatement st = conn.prepareStatement("Select id from regions where id=ANY(?::bigint[])");
Long[] params = new Long[3];
params[0] = Long.valueOf(10);
params[1] = Long.valueOf(20);
params[2] = Long.valueOf(30);
Array arr = new LongArray(params);
st.setArray(1, arr);
ResultSet rs = st.executeQuery();
while (rs.next()){
System.out.println("ID=" + rs.getLong("id"));
}
private static class LongArray implements Array{
Long[] items;
public LongArray(Long[] items){
this.items = items;
}
@Override
public int getBaseType() throws SQLException {
return Types.BIGINT;
}
@Override
public String getBaseTypeName() throws SQLException {
return"int4";
}
@Override
public String toString(){
final StringBuilder builder = new StringBuilder("{");
for (int i = 0; i < items.length; i++){
builder.append(items[i]);
if (i < items.length - 1){
builder.append(',');
}
}
builder.append('}');
System.out.println(builder.toString());
return builder.toString();
}
}
Все функции в LongArray, что не привел возвращают null
Re: Передача параметров в JDBC в условие типа 'in'
Здравствуйте, Аноним, Вы писали:
А>Здравствуйте.
А>Столкнулся со следующей проблемой. А>Есть sql-запрос типа А>select... А>from... А>where field in(?) А>order by... А>так вот, при передаче в качестве второго параметры строки типа "A,B,C" строка парсится и проверяется только вхождение 'A', а наличии 'B' и 'C' игнорируются. А>Загвоздка в том что заранее количество параметров для условия IN неизвестно по этому поставить определенное количество ? нельзя. А>Может кто сталкивался с такой задачей, подскажите, пожалуйста. А>P.S. использую PreparedStatement
я для оракла в таких случаях использую массив, и биндю как statement.setArray(,)
да, перед этим там надо создавать arraydescriptor