На самом деле оператор in() может быть намного быстрее, но поставляется с (пренебрежимой) стоимостью синтаксического анализа плюс ограничение использования до 500 элементов, а также ограничение общего размера текста запроса sql. Таким образом, это достаточно хорошо, но не является ракетным доказательством :)
Ракетно-защитное решение должно передавать произвольное количество параметров в отдельный вызов, а затем иметь представление (или любым другим способом) для представления их в SQL и использовать в своих критериях.
Вариант перебора здесь http://tkyte.blogspot.hu/2006/06/varying-in-lists.html
Однако, если вы можете использовать PL/SQL, этот беспорядок может стать очень аккуратно.
function getCustomers(in_customerIdList clob) return sys_refcursor is
begin
aux_in_list.parse(in_customerIdList);
open res for
select *
from customer c,
in_list v
where c.customer_id=v.token;
return res;
end;
Затем вы можете передать произвольное количество разделенных запятыми идентификаторов клиента в параметре, а также:
- не получат задержку синтаксического анализа, как SQL для выбора является стабильной
- SQL, использует простое соединение, а не оператор IN, что довольно быстро
- В конце концов, это хорошее эмпирическое правило , а не, попадающее в базу данных с любым простым выбором или DML, поскольку это Oracle, который предлагает светлые годы больше, чем MySQL или аналогичные простые базы данных. PL/SQL позволяет скрыть модель хранилища от вашей модели домена приложения эффективным способом.
Хитрость здесь:
- нам нужен вызов, который принимает длинную строку и хранить где-нибудь, где дб сеанс может получить доступ к нему (например, простой переменной пакета, или dbms_session.set_context)
- тогда нам нужно представление, которое может разобрать это на строки
- , а затем у вас есть представление, которое содержит идентификаторы, которые вы запрашиваете, поэтому вам нужно простое соединение с запрошенной таблицей.
мнение выглядит следующим образом:
create or replace view in_list
as
select
trim(substr (txt,
instr (txt, ',', 1, level ) + 1,
instr (txt, ',', 1, level+1)
- instr (txt, ',', 1, level) -1)) as token
from (select ','||aux_in_list.getpayload||',' txt from dual)
connect by level <= length(aux_in_list.getpayload)-length(replace(aux_in_list.getpayload,',',''))+1
где aux_in_list.getpayload относится к исходной строке ввода.
Да, я знаю 1000 предел в разделе IN. Вы знаете лучший способ, чем повторять добавление ',' и '?' в разделе IN, поскольку мои данные для предложения IN находятся в ArrayList? –
[Эта статья] (http://stackoverflow.com/questions/178479/preparedstatement-in-clause-alternatives) имеет несколько альтернатив для динамического генерации запроса с помощью заполнителей привязки. –