Pregunta

¿Hay alguna forma de crear consultas en una fuente de datos (podría ser sql, oracle o access) que tenga una cláusula where que apunte a una ArrayList o List?

ejemplo:

Select * from Table where RecordID in (RecordIDList)

He visto algunas formas de hacerlo con Linq, pero preferiría no recurrir a él si es evitable.

¿Fue útil?

Solución

Puedes usar String.Join . Intenta algo como esto:

String query = "select * from table where RecordId in ({0});";
String formatted = String.Format(query, String.Join(",", list.ToArray()));

Como nota al margen, esto no lo protegerá contra la inyección de SQL; es de esperar que este ejemplo le dirija en la dirección correcta.

Otros consejos

Linq a Sql. RecordList debe ser un List < T > , no un ArrayList o un IList<T>

IEnumerable<TableRow> query =
  from t in db.Table
  where RecordList.Any(r => t.RecordId == r)
  select t;

Esto generará sql con parámetros:

SELECT *
FROM Table
WHERE RecordId in (@p0, @p1, @p2, @p3, @p4)

Linq generará tantos parámetros como sean necesarios. Algunas implementaciones de bases de datos están limitadas en la cantidad de parámetros que pueden aceptarse. El límite de SqlServer2005 es un poco más de 2000 parámetros ... así que no use una lista con más de 2000 elementos.

Solo he hecho lo que intentas hacer con una lista separada por comas

Select * from Table where RecordID in (1,2,34,45,76,34,457,34)

o de dónde provienen los resultados de una selección separada

Select * from Table where RecordID in (select recordId from otherTable where afieldtype=1)

Estoy bastante seguro de que no puedes lograr lo que buscas ...

Puede iterar sobre su matriz y agregar un parámetro a su SQL para cada uno. Esto le ayuda a evitar la inyección de SQL, pero asegúrese de usar un StringBuilder en lugar de una concatenación de cadenas a medida que construye su declaración SQL.

por ejemplo

StringBuilder sql = new StrignBuilder("select * from Table where ");
for  (int i = 0; i < RecordIDLis.Length; i++)
{
    if (i > 0) sql.Append (" OR ");
    sql.Append(" RecordID = @param" + i.ToString() + " ");
    IDbDataParameter param = new Param();
    param.value etc.
}

Puede escribir una función definida por el usuario con valores de tabla que tome una lista de ID y cree una tabla, luego únase nuevamente contra el resultado de esta función. Este artículo de Erland Sommarskog describe cómo hacerlo.

O, podría usar parámetros de tabla, nuevos en SQL Server 2008 (creo).

O, como dijo Manu, puedes usar XML.

Sin embargo, aconsejo no usar el enfoque IN String.Join en la respuesta aceptada, ya que es como pedir una inyección SQL.

Usando Linq to SQL y supongo que Entity Framework puede hacer lo siguiente:

dataContext.Table.Where(t => RecordIDList.Contains(t.RecordID));

Trabajará con ambas listas < > y ArrayList, ya que ambos implementan IEnumerable.

Linq y Lambdas requieren que invierta el método Contains pero funciona y genera un SQL '' IN () '' cláusula.

Si usa SQL dinámico, puede enviar el contenido de los paréntesis como una lista literal separada por comas. De lo contrario, puede usar una variable XML para enviar múltiples valores. Consulte http://vyaskn.tripod.com/passing_arrays_to_stored_procedures.htm

Tenga en cuenta que Linq to SQL = dead, Fuente: http://blogs.msdn.com/adonet/archive/2008/10/29/update-on-linq-to-sql-and-linq -to-entidades-roadmap.aspx

El marco de la entidad es lo que debe usar actualmente si desea implementar dicha arquitectura.

Además, si está utilizando otra consulta de selección (como sugiere GordonB) para su " en " cláusula sería mejor usar "existe" en lugar de " en " por ejemplo:

select * from tablename where exists (select id from othertablename where fieldtype=1)
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top