2009-03-02 5 views
10

Existe-t-il un moyen de créer une requête sur une source de données (sql, oracle ou access) ayant une clause where qui pointe vers une ArrayList ou List?SQL Sélectionnez les valeurs dans la liste <string>

exemple:

Select * from Table where RecordID in (RecordIDList) 

Je l'ai vu quelques façons de le faire avec LINQ, mais je préfère ne pas y recourir si elle est évitable.

Répondre

12

Vous pouvez utiliser String.Join. Essayez quelque chose comme ceci:

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

Comme une note de côté ce qui ne vous protège pas contre l'injection SQL - je l'espère cet exemple, vous pointera dans la bonne direction.

+0

La signature pour string.join est en fait (string, string []) si l'appel regarderait plus exactement comme string.join ("", list.ToArray()). – mquander

+0

Bon appel - Je l'ai réparé! –

+0

J'irais plus loin que votre déclaration "ne vous protégera pas contre l'injection SQL" et dire que ces choses sont la mère de toutes les injections SQL. La meilleure approche est cependant beaucoup plus de travail. – erikkallen

6

Je n'ai fait ce que vous essayez de faire avec une liste séparée par des virgules

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

ou lorsque les résultats proviennent d'une séparée sélectionnez

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

Je suis sûr que vous ne peut pas atteindre ce que vous recherchez ....

7

Linq à Sql. Devrait être une liste des enregistrements List<T>, pas un ArrayList ou un IList<T>

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

Cela va générer sql avec des paramètres:

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

Linq va générer autant de paramètres que sont nécessaires. Certaines implémentations de base de données sont limitées dans le nombre de paramètres pouvant être acceptés. La limite de SqlServer2005 est un peu plus de 2000 paramètres ... donc n'utilisez pas une liste avec plus de 2000 éléments.

0

En utilisant LINQ to SQL et je suppose que le Entity Framework, vous pouvez effectuer les opérations suivantes:

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

fonctionne aussi bien avec liste <> et ArrayList comme ils ont tous deux mettre en œuvre IEnumerable. Linq et Lambdas nécessitent que vous inversiez la méthode Contient mais cela fonctionne et génère une clause SQL "IN()".

-4

S'il vous plaît noter LINQ to SQL = mort, Source: http://blogs.msdn.com/adonet/archive/2008/10/29/update-on-linq-to-sql-and-linq-to-entities-roadmap.aspx

cadre

entité est ce que vous devez utiliser actuellement si vous voulez mettre en œuvre une telle architecture.

En outre, si vous utilisez une autre requête de sélection (comme GordonB suggère) pour votre « dans » l'article, il serait préférable d'utiliser « existe » au lieu de « dans », par exemple:

select * from tablename where exists (select id from othertablename where fieldtype=1) 
+0

JoelHess n'a pas posé de question sur LinqToSql ... la question inclut Oracle, donc LinqToSql aurait dû être exclu par cette exigence. –

1

Vous pouvez écrire une fonction définie par l'utilisateur de type table qui prend une liste d'ID et crée une table, puis joint le résultat de cette fonction. Ce article by Erland Sommarskog décrit comment le faire. Ou, vous pouvez utiliser les paramètres de table, nouveau dans SQL Server 2008 (je pense). Ou, comme l'a dit Manu, vous pouvez utiliser XML. Cependant, je déconseille d'utiliser l'approche IN String.Join dans la réponse acceptée car cela revient à demander une injection SQL.

4

Vous pouvez parcourir votre tableau et ajouter un paramètre à votre SQL pour chacun. Cela vous permet de contourner l'injection SQL, mais assurez-vous d'utiliser un StringBuilder plutôt que d'enchaîner la concaténation lorsque vous créez votre instruction SQL.

par exemple.

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. 
} 
Questions connexes