Вопрос по параметрам в sql

GayRabbit

вобщем-то есть такой код (жава, коннект к ibm db2)
 
PreparedStatement ins = conReg.prepareStatement("insert into sheme.table1 (re, changedate, id) select re, '2009-01-01', ? from scheme.table2 as man where man.id = ?");

ins.setString(1, "123");
ins.setString(2, "345");

ins.executeUpdate;

собсно запрос не выполняется, потому что первый параметр нельзя таким образом использовать. как это можно обойти?
примечание: вот такой запрос
 "insert into sheme.table1 (re, changedate, id) select re, '2009-01-01', '123' from scheme.table2 as man where man.id = ?"
выполняется на ура, но нужно именно с параметром, т.к. иначе стэйтменты будут плодиться очень большим количеством, а это есть не гут.
заранее спосебо.

pitrik2

т.к. иначе стэйтменты будут плодиться очень большим количеством, а это есть не гут.
непонятно чт оыт тут имеешь ввиду
биндинг параметров используется для того чтобы оракл запрос распарсил один раз и потом не тратил время на его парсинг, а только параметры подставлял
если у тебя в запросе меняется структура - то запрос не может быть не перепарсен, т.е. он по-любому перепарситься
т.е. это было бы тоже самое что
PreparedStatement ins = conReg.prepareStatement("insert into sheme.table1 (re, changedate, id) select re, '2009-01-01', " + "123" + " from scheme.table2 as man where man.id = ?");

GayRabbit

ну да, а я 1 раз делаю стэйтмент и потом просто значения подставляю. А подставлять приходится очень много раз, до нескольких миллионов может доходить. Поэтому конструкция с разорванной строкой не подходит, мне тогда придется каждый раз делать стэйтмент, потом его закрывать.

katrin2201

используй обычный "insert into values ", где во вторую скобку в нужном месте воткни ?, в нужном месте вложенный селект

pitrik2

ну да, а я 1 раз делаю стэйтмент и потом просто значения подставляю. А подставлять приходится очень много раз, до нескольких миллионов может доходить. Поэтому конструкция с разорванной строкой не подходит, мне тогда придется каждый раз делать стэйтмент, потом его закрывать.
несоклько миллионов столбцов?
ты ничего не путаешь?
оракл на месте первого вопросика ожидает что ты ей дашь стаолбец из второго селекта
если ты там не столбец передаешь а данные, то поменяй весь запрос так чтобы вопросики ты в данные подставлял а не в структуру
один из вариантов тебе предложил телепат

serega1604

>оракл
вроде в первом посте четко обозначена база, чего ты оракл-то приплетаешь везде?

pitrik2

гы
глюки :)

GayRabbit

так не получается, пробовал... он не умеет, когда селект не 1 столбец, а несколько возвращает
т.е. такая конструкция - insert into schema.table (a, b, c, d) values select a,b,c from schema.table2 d_value) не прокатывает. ошибку дает что нельзя неск столбцов. если один - то пожалста. но тогда на каждый столбец надо свой селект, а это треш, ибо столбцов больше 100, у меня просто упрощенный запрос написан
а про миллион - я имел ввиду количество строк, а не столбцов. т.е. грубо говоря код такой
 

PreparedStatement st ...........

for(int i=0; i < 1000000000; i++) {

st.setString(1, string_array[i]);
st.executeUpdate;
con.commit;

}

st.close;

pitrik2

как вариант сделать это хранимой процедурой
ну только всё равно это не совсем правильно, в том смысле что парсинг запроса в бд не скешируется, но зато тебе не надо строчки свои генерить
попробуй еще какиенить варианты для создания таблицы из строчки
я db2 особо не знаю, но как-то же наверняка там можно создать таблицу
типа
select my from values(my=?);
а потом эту таблицу с одной записью объединить с твоей
insert into schema.table (a, b, c, d) values (select a,b,c,my.my from schema.table2, (хитрая конструкция) as my))

pitrik2

ну кстати
продолжая эту мысль можно в 3 вызова это сделать :)

PreparedStatement st = "insert into schema.table (a, b, c, d) values (select a,b,c,my.my from schema.table2, (select * from my) as my)";
Statement st2 = "delete from my";
PreparedStatement st3 = "insert into my values(?)";

for(int i=0; i < 1000000000; i++) {

st2.executre; // clear my table
st3.setString('lalala');
st3.execute; // fill my table

   st.setString(1, string_array[i]);
   st.executeUpdate;
   con.commit;

}

st.close;

ппц кривое решение, но зато работает :)

GayRabbit

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

katrin2201

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

GayRabbit

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