119 votes

Existe-t-il un meilleur moyen de créer de manière dynamique une clause SQL WHERE qu'en utilisant 1 = 1 au début?

Je construis une requête SQL en C #. Il diffère en fonction de certaines conditions stockées en tant que variables dans le code.

 string Query="SELECT * FROM Table1 WHERE 1=1 ";
if (condition1) 
    Query += "AND Col1=0 ";
if (condition2) 
    Query += "AND Col2=1 ";
if (condition3) 
    Query += "AND Col3=2 ";
 

Cela fonctionne, mais tester 1 = 1 ne semble pas élégant. Si je ne l'utilisais pas, je devrais me rappeler et vérifier chaque fois si le mot clé "où" était déjà ajouté ou non à la requête.

Y a-t-il une solution plus intéressante?

164voto

Ahmed KRAIEM Points 6414

Enregistrez les conditions dans une liste:

 List<string> conditions = new List<string>();

if (condition1) conditions.Add("Col1=0");
//...
if (conditions.Any())
    Query += " WHERE " + string.Join(" AND ", conditions.ToArray());
 

87voto

CodeCaster Points 38181

Une solution consiste simplement à ne pas écrire manuellement les requêtes en ajoutant des chaînes. Vous pouvez utiliser un ORM, comme Entity Framework , et avec LINQ to Entities utiliser les fonctionnalités offertes par le langage et la structure:

 using (var dbContext = new MyDbContext())
{
    IQueryable<Table1Item> query = dbContext.Table1;

    if (condition1)
    {
        query = query.Where(c => c.Col1 == 0);
    }
    if (condition2)
    {
        query = query.Where(c => c.Col2 == 1);
    }
    if (condition3)
    {
        query = query.Where(c => c.Col3 == 2);
    }   

    PrintResults(query);
}
 

18voto

AlanBarber Points 802

Un peu d'overkill dans ce cas simple mais j'ai utilisé un code similaire à celui-ci dans le passé.

Créer une fonction

 string AddCondition(string clause, string appender, string condition)
{
    if (clause.Length <= 0)
    {
        return String.Format("WHERE {0}",condition);
    }
    return string.Format("{0} {1} {2}", clause, appender, condition);
}
 

Utilisez-le comme ça

 string query = "SELECT * FROM Table1 {0}";
string whereClause = string.Empty;

if (condition 1)
    whereClause = AddCondition(whereClause, "AND", "Col=1");

if (condition 2)
    whereClause = AddCondition(whereClause, "AND", "Col2=2");

string finalQuery = String.Format(query, whereClause);
 

De cette façon, si aucune condition n'est trouvée, vous ne vous souciez même pas de charger une instruction where dans la requête et de sauvegarder le serveur SQL une micro-seconde de traitement de la clause Junk Where quand il analyse l'instruction SQL.

15voto

Dariusz Points 8058

Il existe une autre solution, qui peut aussi ne pas être élégante, mais qui fonctionne et résout le problème:

 String query = "SELECT * FROM Table1";
List<string> conditions = new List<string>();
// ... fill the conditions
string joiner = " WHERE ";
foreach (string condition in conditions) {
  query += joiner + condition;
  joiner = " AND "
}
 

Pour:

  • liste des conditions vides, le résultat sera simplement SELECT * FROM Table1 ,
  • une seule condition sera SELECT * FROM Table1 WHERE cond1
  • chaque condition suivante générera des AND condN supplémentaires

8voto

Anshuman Points 290

Utilisez ceci:

 string Query="SELECT * FROM Table1 WHERE ";
string QuerySub;
if (condition1) QuerySub+="AND Col1=0 ";
if (condition2) QuerySub+="AND Col2=1 ";
if (condition3) QuerySub+="AND Col3=2 ";

if (QuerySub.StartsWith("AND"))
    QuerySub = QuerySub.TrimStart("AND".ToCharArray());

Query = Query + QuerySub;

if (Query.EndsWith("WHERE "))
    Query = Query.TrimEnd("WHERE ".ToCharArray());
 

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X