2009-05-10 12 views
26

Experimento con LINQ desde hace algún tiempo. método típico para enumerar a través de una colección y cambiar algunas de sus propiedades en mi código se vería así:número máximo de parámetros en la consulta SQL

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(); 
} 

algún tiempo un tengo un consejo para hacer esto ... que parece ser mucho más inteligente manera:

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(); 

Iit tiene sentido en muchos niveles y me encanta esta solución. Es inteligente y más rápido que el primero.

He usado esta solución en un entorno de producción durante algún tiempo.

¿Cuál fue mi sorpresa después de unas semanas cuando se busca un archivos de registro de aplicación y ver esto:

"La secuencia de datos tabular (TDS) entrante llamada a procedimiento remoto (RPC) de la secuencia del protocolo es incorrecta demasiados parámetros. se proporcionaron en esta solicitud de RCP. El máximo es 2100 ".

El LINQ a SQL convierte where col.Contains(r.ID) a IN cláusula buscando algo como:
donde id IN (@ p1, @ p1, @ p2 ...)

La colección col alcanzado (en mi caso) más de 2100 elementos y la consulta no se realizó. He hecho algunas investigaciones sobre el problema y lo que terminó es:

“... El número máximo de parámetros en la consulta SQL es 2100. Hay más limitaciones, como el hecho de que toda la cadena de consulta no puede ser más largo de 8044 caracteres. "

Me gustó tanto la segunda solución. Estoy tan decepcionado con estas limitaciones codificadas del SQL Server.

¿Echo de menos algo? ¿Hay algo que pueda hacer para poder utilizar la versión "where col.Contains (r.ID)"?

Saludos Mariusz

ps. (Uso Win XP, C# con LINQ y SQL 2005 Express).

+0

Disculpas. No logré formatear muestras de código. Si alguien pudiera ayudar, apreciaría mucho ... – Mariusz

+0

formateado; puede usar los botones "codificar" y "citar" para hacer esto en el editor. –

+0

muchas gracias. simplemente investigando tu otra respuesta. parece que no será sencillo :-) – Mariusz

Respuesta

39

Los límites are hard-coded:

  • parámetros por procedimiento almacenado 2.100
  • parámetros por función definida por el usuario 2.100

I escribieron algo de código antes de esa fracción de la consulta Contains en lotes y se combinaron la resultados ... see here for more.

+5

resulta que el mensaje de error/la documentación es incorrecta.Deben tener una comprobación que va '> = 2100' en lugar de> 2100 porque el límite real es 2099, solo se observó esto al intentar enviar un lote de 4 parámetros, lo que da un tamaño par de 525 –

+1

@JonnyLeeds interesante; Me pregunto si hay algo así como incluir siempre espacio para un valor de retorno (incluso si no se usa), que se implementa como un parámetro –

+0

, sí, posiblemente. La documentación allí menciona específicamente funciones y procedimientos almacenados, mientras que yo solo estaba ejecutando un gran conjunto de insertos, sin embargo, las excepciones de ejecutar 'command.Execute [Blah]' (en C#) también mencionan 2100 –

Cuestiones relacionadas