2010-08-04 8 views
2

J'ai une application ASP.NET qui doit rechercher une colonne VARCHAR (20) en utilisant des listes et des plages. En d'autres termes, l'entrée pourrait être quelque chose comme:Listes de recherche, plages

ABC,444,CD-EF,90-BA,HIJ 

et le résultat doit être l'équivalent de:

SELECT * FROM table 
WHERE 
    Col1 = 'ABC' OR 
    Col1 = '444' OR 
    Col1 BETWEEN 'CD' AND 'EF' OR 
    Col1 BETWEEN '90' AND 'BA' OR 
    Col1 = 'HIJ' 

L'ordre de tri régulier colonne SQL est acceptable pour les plages. Il y a deux parties principales impliquées ici:

  1. Envoi des paramètres de .NET à une procédure stockée. Utilisation des paramètres du SP pour effectuer une recherche.

Quelques options que j'ai considéré, qui ne sont pas mutuellement exclusives:

  1. je pourrais envoyer la chaîne comme il est. Il n'y a pas array[] = SPLIT(',', @query) ou similaire, donc l'analyse serait de bas niveau. Je préfère faire l'analyse du côté .NET.
  2. Coté .NET, convertir en XML, dans SP convertir en table.
  3. Utilisez un curseur pour parcourir les paramètres déjà présents dans la table, effectuer des requêtes séparées et fusionner les résultats.
  4. Créer une dynamique où la clause (sur le côté SQL aveC# 1, ou sur le côté .NET)

SQL dynamique sur le côté .NET semble être le moyen « facile », mais je ne suis pas convaincu que c'est le meilleur. Des pensées?

Répondre

1

Je pense que la création de l'instruction SQL sur le côté .NET est plus que la solution de facilité. SQL est plus performant lorsque vous effectuez des opérations set-base (par exemple, exécuter une instruction SELECT). SQL n'est pas le meilleur choix lors du codage procédural.

Lors de l'adressage de chacune de vos options autres que la création de SQL dynamique côté .NET, vous demandez à SQL de procéder de manière procédurale.

Comme vous pouvez avoir .NET faire les choses procédurales et SQL Server faire les trucs basés sur les ensembles, c'est la voie à suivre.

+0

J'ai fini par le faire de cette façon.Garder le côté serveur a ajouté un peu de réutilisation, mais la valeur était négligeable pour l'effort. –

1

Pour ce faire, dans SQL Server, vous devez diviser une chaîne/VARCHAR en une table temporaire qui peut ensuite utiliser JOINs pour filtrer la table cible.

Consultez cet excellent article MSDN sur la construction de requêtes à l'aide d'une entrée codée. Comprend une fonction SQL pour Varchars délimités par des caractères déchirants:

http://code.msdn.microsoft.com/SQLExamples/Wiki/View.aspx?title=StringArrayInput&referringTitle=Home

Cela très bien pour les comparaisons d'égalité - les entre les opérations vont être plus délicat à mettre en œuvre. Compte tenu des limitations de la manipulation de chaînes SQL par rapport à C#, je finirais par l'implémenter en C#.

+0

+1 pour le côté SQL, même si j'ai fini par ne pas l'utiliser. –

2

Que diriez-vous juste de créer l'instruction SQL en C#. Cela implique que vous avez le contrôle sur votre chaîne d'entrée afin de ne pas être sujette aux attaques par injection SQL.

string para = "ABC,444,CD-EF,90-BA,HIJ"; 
StringBuilder sb = new StringBuilder("SELECT * FROM table WHERE "); 
List<string> queries = new List<string>(); 
foreach (var part in para.Split(',')) 
{ 
    if (part.Contains("-")) 
    { 
     var between = part.Split('-'); 
     queries.Add(string.Format("Col1 BETWEEN '{0}' AND '{1}'", between[0], between[1])); 
    } 
    else 
    { 
     queries.Add(string.Format("Col1 = '{0}'", part)); 
    } 
} 
sb.Append(string.Join(" OR ", queries.ToArray())); 
string sql = sb.ToString(); 
+0

+1 par exemple, même si j'avais déjà mentionné cette option et je savais comment le faire. –

Questions connexes