Максимальное количество параметров в SQL-запросе
Я экспериментирую с LINQ с некоторого времени. Типичный метод для перечисления в коллекции и изменения некоторых ее свойств в моем коде будет выглядеть так:
ATDataContext dc = new ATDataContext(Settings.connection_string);
int[] col = ListViewClass.getListViewSelectedPositionTags(listView);
try
{
foreach (var item in col)
{
var ctx = (from r in dc.MailingLists
where r.ID == item
select r).Single();
ctx.Excluded = 'Y';
ctx.ExcludedComments = reason;
}
dc.SubmitChanges();
}
Некоторое время у меня есть совет, чтобы сделать это... кажется более умным способом:
var ctx = from r in dc.MailingLists
where col.Contains(r.ID)
select r;
foreach (var item in ctx)
{
item.Excluded = 'Y';
item.ExcludedComments = reason;
}
dc.SubmitChanges();
Это имеет смысл на многих уровнях, и мне нравится это решение. Это умно и быстрее, чем первый.
Я использовал это решение в производственной среде в течение некоторого времени.
Каково было мое удивление после нескольких недель поиска файлов журнала приложения и просмотра этого:
"Поток протокола удаленного вызова процедур (RPC) входящего потока табличных данных (TDS) неверен. В этом запросе RCP было предоставлено слишком много параметров. Максимум - 2100".)
LINQ to SQL конвертирует where col.Contains(r.ID)
в IN
пункт выглядит примерно так:
ГДЕ ИДЕНТИФИКАЦИЯ (@p1, @p1, @p2 …)
col
Коллекция достигла (в моем случае) более 2100 элементов, и запрос не удалось выполнить. Я провел некоторое исследование по проблеме, и в итоге я получил:
"… Максимальное количество параметров в запросе sql составляет 2100. Существует больше ограничений, например, тот факт, что вся строка запроса не может быть длиннее 8044 символов".
Мне так понравилось второе решение. Я так разочарован этими жестко закодированными ограничениями SQL Server.
Я что-то пропустил? Могу ли я что-нибудь сделать, чтобы использовать версию "где col.Contains(r.ID)"?
С уважением Мариуш
пс. (Я использую Win XP, C# с LINQ и SQL 2005 Express).
1 ответ
Ограничения жестко закодированы:
- Параметры для хранимой процедуры 2100
- Параметры для определенной пользователем функции 2100
Я написал некоторый код до того, как Contains
запросить в пакетах и объединить результаты... см. здесь для получения дополнительной информации.