2010-03-24 6 views
1

Je suis à la recherche d'un exemple de script. J'en ai vu un hier mais pour la vie de moi je ne peux plus le retrouver aujourd'hui. La tâche que j'ai est de permettre à l'utilisateur de rechercher 1 table de base de données via des contrôles de saisie sur une page ASPX où ils peuvent sélectionner et/ou combiner des champs, générer le sql à la volée avec concat/stringbuilder ou similaire . (Il court derrière le pare-feu corp)Un exemple de recherche de base de données avancée

S'il vous plaît quelqu'un peut me diriger dans la bonne direction d'un exemple ou tutoriel

Je travaille sur la page, mais ont des problèmes. Voici le Page_load;

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load 
    Dim sql As String = ("Select * From Table Where ") 

    'variables to hold the and or values between fields 
    Dim andor1v As String = AndOr1.SelectedValue.ToString() 
    Dim andor2v As String = AndOr2.SelectedValue.ToString() 
    Dim andor3v As String = AndOr3.SelectedValue.ToString() 
    Dim andor4v As String = AndOr4.SelectedValue.ToString() 
    Dim andor5v As String = AndOr5.SelectedValue.ToString() 
    Dim andor6v As String = AndOr6.SelectedValue.ToString() 

    'variables to stop web control inputs going direct to sql 
    Dim name As String = NameSearch.Text.ToString() 
    Dim email As String = EmailSearch.Text.ToString() 
    Dim city As String = CitySearchBox.Text.ToString() 
    Dim province As String = ProvinceSelect.SelectedValue.ToString() 
    Dim qualifications As String = QualificationsObtained.Text.ToString() 
    Dim competencies As String = CompetenciesDD.SelectedValue.ToString() 
    Dim expertise As String = Expertiselist.SelectedValue.ToString() 

    If NameSearch.Text IsNot String.Empty Then 
     sql += "Surname LIKE '%" & name & "%' " 
    End If 

    If EmailSearch.Text IsNot String.Empty Then 
     sql += andor1v & " Email LIKE '%" & email & "%' " 
    End If 

    If CitySearchBox.Text IsNot String.Empty Then 
     sql += andor2v & " City LIKE '%" & city & "%' " 
    End If 

    If QualificationsObtained.Text IsNot String.Empty Then 
     sql += andor3v & " (institutionquals1 LIKE '%" & qualifications & "%') OR " & _ 
     "(institutionquals2 LIKE '%" & qualifications & "%') OR " & _ 
     "(institutionquals3 LIKE '%" & qualifications & "%') OR " & _ 
     "(institutionquals4 LIKE '%" & qualifications & "%') " 
    End If 

    Dim selectedrow As String = CompetenciesDD.SelectedValue.ToString 
    Dim selectedquals As String = NQFlevel.SelectedValue.ToString 
    If CompetenciesDD.SelectedValue.ToString IsNot "0" And selectedquals = 0 Then 
     sql += (selectedrow & " = 1 ") 

    ElseIf selectedrow = "assessortrue" And selectedquals IsNot "0" Then 
     sql += andor4v & (" assessortrue=1 and assessorlvl=" & selectedquals) 
    ElseIf selectedrow = "coordinatortrue" And selectedquals IsNot "0" Then 
     sql += andor4v & ("coordinatortrue=1 and coordinatorlvl=" & selectedquals) 
    ElseIf selectedrow = "facilitatortrue" And selectedquals IsNot "0" Then 
     sql += andor4v & ("facilitatortrue=1 and facilitatorlvl=" & selectedquals) 
    ElseIf selectedrow = "moderatortrue" And selectedquals IsNot "0" Then 
     sql += andor4v & ("moderatortrue=1 and moderatorlvl=" & selectedquals) 
    ElseIf selectedrow = "productdevelopertrue" And selectedquals IsNot "0" Then 
     sql += andor4v & ("productdevelopertrue=1 and productdeveloperlvl=" & selectedquals) 
    ElseIf selectedrow = "projectmanagertrue" And selectedquals IsNot "0" Then 
     sql += andor4v & ("projectmanagertrue=1 and projectmanagerlvl=" & selectedquals) 
    End If 

    Response.Write(sql) 

End Sub 

Après une heure de bricoler le code cherche maintenant comme il le fait ci-dessus^

Maintenant im problème face à est si un utilisateur ne saisit pas de valeur pour le nom (le premier champ) mais ne pénètre une valeur pour l'email (ou n'importe quels champs suivants), le sql produit a un extra et comme ceci;

Select * From Table Where And Email LIKE '%test%' 

Je suis également à la recherche d'un moyen de prendre en compte l'option OU. Pensez-vous que cela devrait être fait comme Martin dit où toute la requête est soit un et/ou un et/ou pas un mélange des 2? Ensuite, je devrais être en mesure de sortir tous les et/ou déroulants?

Merci. NB: Je ne suis pas vraiment à la recherche de commentaires sur la façon dont je devrais paramétrer ou sur l'injection de SQL. La concaténation de chaînes pour créer une requête n'est jamais une bonne idée.

+0

Vous aurez certainement envie de remplacer "à « » peu importe combien vous faites confiance à vos utilisateurs comme ils recherchent O'Reilly il se brisera. Voir aussi Injection SQL. –

+0

quels problèmes avez-vous? cela ressemble à la "qualité" SQL dynamique mais il semble manquer une certaine logique, pouvez-vous poster plus de code? – andrewWinn

+0

@andrewWin. ont posté du code complet et plus d'infos sur le prob, merci. – Phil

Répondre

1

En ce qui concerne votre problème avec les utilisateurs ne sélectionnant pas une option, vous pouvez simplement supprimer le "s'il vous plaît sélectionner" et l'avoir par défaut "et "

De même, quel est le comportement souhaité s'ils sélectionnent un mélange d'AND et d'OR?

Par défaut, les ANDs seront évalués d'abord en l'absence de supports

http://msdn.microsoft.com/en-us/library/ms186992.aspx

Donc, s'ils entrent

name = "Fred" ou email = "bla" et city ​​= "london" et province = "xyz" ou qualifications = "Degré"

Je ne suis pas vraiment sûr de ce que serait la sémantique désirée?

Est-il

(name = "Fred" ou email = "bla") et ville = "london" et (province = "xyz" ou qualifications = "degré")

ou

(name = "Fred" ou (email = "bla" et ville = "londres") et province = "xyz") ou qualifications = "degré"

Ou quelque chose de différent? Peut-être devriez-vous les restreindre à ET ou OU pour toute la requête ou leur permettre de désambiguïser soit en tapant dans la syntaxe de recherche avancée avec des crochets ou en fournissant une interface utilisateur de création de requête.

+0

Je pense que je dois concaténer les parenthèses quand ou est sélectionné. donc chacun est évalué séparément. – Phil

+0

@Martin Re: Je ne suis pas vraiment sûr de ce que serait la sémantique souhaitée? Sanglante bonne question. Je pense que je devrais parler au propriétaire du projet! – Phil

0

Vous devez utiliser une procédure stockée ou des requêtes paramétrées.

+0

Aucune procédure stockée autorisée pour ce proj (commandes de boss). Il fonctionne à l'intérieur du pare-feu, auth'd contre AD, à l'intérieur de la zone d'administration. Je ne suis pas sûr que j'aurais pu utiliser des params pour cette situation, surtout en fournissant des noms dynamiques. – Phil

+1

Je ne suis pas du tout d'accord pour mettre ce type de code dans un proc. TSQL et les capacités de manipulation et de test de chaînes d'âge de pierre. Les requêtes de recherche sql dynamiques typiques sont vraiment une forme de génération de code et si vous mettez ce code dans un environnement où vous ne pouvez pas effectuer de tests unitaires et l'intention est perdue dans une mer de codes d'échappement (parfois TSQL nécessite cinq, six ou plus citations dans une rangée pour échapper à des scénarios communs!). Je n'ai jamais trouvé de processus de recherche TSQL qui ne soit pas bourré d'opportunités d'injection SQL car le code est si difficile à lire. – MatthewMartin

0

J'ai effectué cette interface de requête de type "dynamique" sur un ASP classique.

Le conseil que je vous donne est que vous essayez de faire toute la requête dans un chargement de la page si ...

Regardez à « construire » la requête via une interface de type « assistant » - soit ajax pour la nouveauté ou plusieurs pages simples pour chaque partie du bâtiment de la requête. C'est l'essence qui vous donne la «persitance» par ce que vous voulez dire (session, dbstore, cookie, etc.) pour chaque partie de la requête et vous pouvez vérifier chaque partie de la requête au fur et à mesure de la construction.

0
Dim sql As String = ("Select * From Table Where **1=1**") 

    'variables to hold the and or values between fields 
    Dim andor1v As String = AndOr1.SelectedValue.ToString() 
    Dim andor2v As String = AndOr2.SelectedValue.ToString() 
    Dim andor3v As String = AndOr3.SelectedValue.ToString() 
    Dim andor4v As String = AndOr4.SelectedValue.ToString() 
    Dim andor5v As String = AndOr5.SelectedValue.ToString() 
    Dim andor6v As String = AndOr6.SelectedValue.ToString() 

    'variables to stop web control inputs going direct to sql 
    Dim name As String = NameSearch.Text.ToString() 
    Dim email As String = EmailSearch.Text.ToString() 
    Dim city As String = CitySearchBox.Text.ToString() 
    Dim province As String = ProvinceSelect.SelectedValue.ToString() 
    Dim qualifications As String = QualificationsObtained.Text.ToString() 
    Dim competencies As String = CompetenciesDD.SelectedValue.ToString() 
    Dim expertise As String = Expertiselist.SelectedValue.ToString() 

    If NameSearch.Text IsNot String.Empty And andor1v IsNot "0" Then 
     sql += "**and** Surname LIKE '%" & name & "%' " 
    ElseIf NameSearch.Text IsNot String.Empty And andor1v Is "0" Then 
     sql += "**or** Surname LIKE '%" & name & "%' " 
    End If 

    ....additional logic here..... 
    Response.Write(sql) 

End Sub 

noter les ** parties. 1 = 1 évalue à vrai sur la plupart des SGBD. Cela vous permet de commencer à concaténer votre/ou et sans vous soucier de()

1

Pour éviter une injection SQL et permettre une recherche dynamique, j'écrirais probablement une procédure stockée quelque chose comme ça. Si rien n'est sélectionné, envoyez DBNull.Value dans la collection de paramètres ado.net en tant que valeur du paramètre. Avec cette approche, vous pouvez vérifier toutes les colonnes que vous voulez et si elles ne sont pas sélectionnées par l'utilisateur, elles seront ignorées.

EDIT: Je viens de voir que vous n'êtes pas autorisé à utiliser les procédures stockées. J'ai changé ma réponse ci-dessous pour afficher une instruction SQL paramétrées

SELECT * FROM TABLE 
WHERE ([name] = @name OR @name IS NULL) 
AND (email = @email OR @email IS NULL) 
AND (city = @city OR @city IS NULL) 
AND (province = @province OR @province IS NULL) 
AND (qualifications = @qualifications OR @qualifications IS NULL) 
AND (competencies = @competencies OR @competencies IS NULL) 
AND (expertise = @expertise OR @expertise IS NULL) 
+0

Salut Jon, Merci beaucoup pour l'aide. Je pense que la phase 2 de mon projet sera de paramétrer une fois que j'ai une démo de travail en utilisant la méthode concat, donc je vais garder cela à l'esprit. – Phil

Questions connexes