2009-03-02 7 views
10

¿Existe alguna manera de que pueda crear una consulta contra un origen de datos (podría ser sql, oráculo o acceso) que tenga una cláusula where que apunte a una ArrayList o lista?SQL Seleccionar dónde están los valores en la Lista <string>

ejemplo:

Select * from Table where RecordID in (RecordIDList) 

He visto algunas maneras de hacerlo con LINQ, pero yo prefiero no recurrir a él si es evitable.

Respuesta

12

Puede usar String.Join. Intentar algo como esto:

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

Como una nota de esto no le protegerá contra la inyección de SQL - esperemos que este ejemplo le apuntan en la dirección correcta.

+0

La firma para string.join es en realidad (String, String []) lo que la llamada se vería más correctamente como string.join ("", list.ToArray()). – mquander

+0

Buena llamada - ¡Lo arreglé! –

+0

Iría más allá de su afirmación "no lo protegeré contra la inyección de SQL" y diría que estas cosas son la madre de todas las inyecciones de SQL. Sin embargo, el mejor enfoque es mucho más trabajo. – erikkallen

6

Sólo he hecho lo que su tratando de hacer con una lista separada por comas

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

o cuando los resultados provienen de una separada seleccione

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

estoy bastante seguro de que no puede lograr lo que busca ...

7

Linq to 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 sea necesario. 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 uses una lista con más de 2000 elementos.

0

mediante LINQ to SQL y supongo que el marco de la entidad que puede hacer lo siguiente:

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

trabajará tanto Lista <> y ArrayList, ya que ambos implementan IEnumerable.

Linq y Lambdas requieren que invierta el método Contiene, pero funciona y genera una cláusula SQL "IN()".

-4

Tenga en cuenta LINQ a SQL = muerto, Fuente: http://blogs.msdn.com/adonet/archive/2008/10/29/update-on-linq-to-sql-and-linq-to-entities-roadmap.aspx

marco de la entidad es lo que debe utilizar actualmente, si se desea implementar este tipo de arquitectura.

Por otra parte, si usted está usando otra consulta de selección (como GordonB sugiere) 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) 
+0

JoelHess no preguntó por LinqToSql ... la pregunta incluye Oracle, por lo que LinqToSql debería haber sido descartado por ese requisito. –

1

Puede escribir una función definida por el usuario con valores de tabla que toma una lista de ID y crea una tabla, luego une el resultado de esta función. Este article by Erland Sommarskog describe cómo hacerlo.

O bien, podría utilizar los parámetros de la tabla, nuevos en SQL Server 2008 (creo).

O, como dijo Manu, puede usar XML.

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

4

Puede iterar sobre su matriz y agregar un parámetro a su SQL para cada una. Esto lo acerca a la inyección SQL, pero asegúrese de utilizar un StringBuilder en lugar de restringir la concatenación a medida que crea su declaración SQL.

p. Ej.

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. 
} 
Cuestiones relacionadas