Ошибка Oracle: максимальное количество выражений в списке равно 1000

Я работаю в С#.Net и Oracle. я передаю строку в запрос. я использовал этот код для объединения всех идентификаторов элементов

List<string> listRetID = new List<string>();
                foreach (DataRow row in dtNew.Rows)
                {
                    listRetID.Add(row[3].ToString());
                }

Эта конкатенация превышает 10 000. поэтому я получаю сообщение об ошибке, подобное этому ..

ORA-01795: maximum number of expressions in a list is 1000

Как это исправить..


person RobinHood    schedule 19.07.2012    source источник
comment
пожалуйста, опубликуйте запрос оракула, выходящий из этого   -  person Satya    schedule 19.07.2012
comment
Нет, я не могу... Это очень большой запрос. Как я уже сказал, ввод для этого запроса содержит строку [Данные concat этой строки пересекают 10000 идентификаторов, разделенных запятыми]   -  person RobinHood    schedule 19.07.2012
comment
затем реструктурируйте свой запрос, так как я не думаю, что добавление 10000 идентификаторов для формирования строки - хорошая идея.   -  person Satya    schedule 19.07.2012
comment
Вот что я спрашиваю, как разбить эту строку...   -  person RobinHood    schedule 19.07.2012


Ответы (4)


Не специалист по С#, но я бы просто разделил список listRetID на несколько списков или создал список списков

Затем прокрутите этот список списков и выполните запрос для каждого элемента списка.

person Hugo    schedule 19.07.2012

В документации указано:

Список выражений, разделенных запятыми, может содержать не более 1000 выражений. Разделенный запятыми список наборов выражений может содержать любое количество наборов, но каждый набор может содержать не более 1000 выражений.

Предположительно, вы используете эту строку как содержимое ограничения IN (...), и в этом случае вы ничего не можете сделать — это просто не сработает. Обычный способ обойти это — создать фиктивную таблицу в качестве подзапроса или общего табличного выражения (CTE) и присоединиться к ней, но я не уверен, как бы вы перевели свой список — возможно, похоже на то, что вы делаете. с вашим пунктом IN. Вы бы хотели, чтобы ваш запрос выглядел примерно так:

with tmp_tab as (
    select <val1 from list> as val from dual
    union all select <val2 from list from dual
    union all select <val3 from list from dual
    ...
)
select <something>
from <your table> yt
join tmp_tab tt on yt.<field> = tt.val

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

Вы можете найти что-то вроде этот подход более приемлем.

person Alex Poole    schedule 19.07.2012
comment
это довольно ясно. Вы должны сделать это в нескольких запросах с пакетами идентификаторов не более 1000 идентификаторов, а затем так или иначе склеить результаты. - person Hugo; 19.07.2012

Вы можете иметь 10 списков из 1000 элементов вместо 1 списка из 10000 элементов.

WHERE some_column IN (1,2,...,1000)
   OR some_column IN (1001,1002,...2000) -- etc.
person jva    schedule 19.07.2012
comment
как я могу взять эти 1000 идентификаторов из списка 10000 идентификаторов ... значения не жестко закодированы. все динамичны. - person RobinHood; 19.07.2012
comment
Извините, я не могу дать вам код C# :( Возможно, вы можете использовать список List‹String› и переключаться на новый элемент после 1000 значений. - person jva; 19.07.2012

Какова цель вашего запроса?

Похоже, вы выбираете строки, в которых есть столбец, равный третьему столбцу одной из записей некоторого запроса.

Правильный способ сделать это — соединение SQL или подзапрос. Нет абсолютно никакой необходимости переносить это в код C#. Например, используя подзапрос, вы можете написать что-то вроде этого:

SELECT *
FROM atable
WHERE afield IN (
    SELECT field3
    FROM someothertable)
person Olaf    schedule 19.07.2012