Question

Existe-t-il un moyen de créer une requête sur une source de données (sql, oracle ou access) comportant une clause where qui pointe vers une liste de tableaux ou une liste?

exemple:

Select * from Table where RecordID in (RecordIDList)

J'ai déjà vu des moyens de le faire avec Linq, mais je préférerais ne pas y recourir si c'est évitable.

Était-ce utile?

La solution

Vous pouvez utiliser String.Join . Essayez quelque chose comme ça:

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

Remarque: cela ne vous protégera pas contre l'injection SQL. J'espère que cet exemple vous guidera dans la bonne direction.

Autres conseils

Linq to Sql. RecordList doit être une liste < 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;

Ceci générera SQL avec les paramètres:

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

Linq générera autant de paramètres que nécessaire. Certaines implémentations de bases 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 ... n'utilisez donc pas de liste contenant plus de 2000 éléments.

Je n'ai fait que 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 si les résultats proviennent d'une sélection séparée

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

Je suis presque sûr que vous ne pouvez pas réaliser ce que vous voulez ....

Vous pouvez parcourir votre tableau et ajouter un paramètre à votre code SQL pour chacun. Cela vous évite l’injection SQL, mais assurez-vous d’utiliser un StringBuilder plutôt que la concaténation de strign lors de la construction de 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.
}

Vous pouvez écrire une fonction définie par l'utilisateur, à valeur de table, qui prend une liste d'identifiants et crée une table, puis joint le résultat de cette fonction. Cet article d'Erland Sommarskog décrit comment procéder.

Vous pouvez également utiliser les paramètres de table, nouveaux dans SQL Server 2008 (je pense).

Ou, comme l'a dit Manu, vous pouvez utiliser XML.

Toutefois, je déconseille d'utiliser l'approche IN String.Join dans la réponse acceptée, car cela revient à demander une injection SQL.

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

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

Travaillera avec les deux listes < > et ArrayList car ils implémentent tous les deux IEnumerable.

Linq et Lambdas requièrent l’inverse de la méthode Contains, mais cela fonctionne et génère un code SQL "IN ()". clause.

Si vous utilisez du SQL dynamique, vous pouvez envoyer le contenu des parenthèses sous forme de liste séparée par des virgules. Sinon, vous pouvez utiliser une variable XML pour envoyer plusieurs valeurs. Voir http://vyaskn.tripod.com/passing_arrays_to_stored_procedures.htm

Veuillez noter que Linq to SQL = dead, Source: http://blogs.msdn.com/adonet/archive/2008/10/29/update-on-linq-to-sql-and-linq -to-entités-roadmap.aspx

Le framework Entity est ce que vous devez utiliser actuellement si vous souhaitez implémenter une telle architecture.

De plus, si vous utilisez une autre requête de sélection (comme le suggère GordonB) pour votre " in " clause, il vaudrait mieux utiliser " existe " au lieu de " dans " par exemple:

select * from tablename where exists (select id from othertablename where fieldtype=1)
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top