14. januar 2005 - 00:02Der er
32 kommentarer og 5 løsninger
Søgning på flere værdier ord1, ord2, ord3
Hejsa!
Jeg har en søgefunktion hvor man skal kunne vælge flere værdier fra en liste som så bliver komma sep. i en QueryString
Men hvis man vælger flere værdier vil den ikke vise resultaterne??
Jeg bruger nedenstående nu???????? Håber der er nogle der kan hjælpe!
if request.QueryString("soegeord") = "" then medlemmer.Source = "SELECT * FROM medlemmer WHERE kommunenr =" & request.QueryString("kommunenr") & " ORDER BY Virksomhedsnavn ASC" else medlemmer.Source = "SELECT * FROM medlemmer WHERE kommunenr =" & request.QueryString("kommunenr") & " AND Fservices LIKE '%" & request.QueryString("soegeord") & "%' ORDER BY Virksomhedsnavn ASC" end if
Husk at dersom request.QueryString("soegeord") returnerer tekst, skal du have enkelt plinger rundt hvert element: "'tekst1', 'tekst2', 'tekst3'". Dette er nok nemmest at lave i den asp der genererer soegeord.
Hvis du bruger LIKE, søger du efter forekomster af Fservices, der indeholder teksten i LIKE. Det er ikke det du ønsker, vil jeg mene. Du ønsker vel forekomster af Fservices hvor Fservices er indeholdt i request.QueryString("soegeord"), ",", "','") ? Hvad med at skrive ud Replace(request.QueryString("soegeord"), ",", "','") og se hvad den indeholder? Eller skriv ud medlemmer.Source med Response.Write, og test direkte mod databasen? Send eventuelt resultatet af Replace(request.QueryString("soegeord"), ",", "','") til eksperten, så kigger jeg på det. Men jeg går nok i seng om lidt.
Du har et komme for meget til sidst. Kan du klare at fjerne det sidste komme inden du sender det i query string, eller skal der bruges noget VBScript til at fjerne det siste tegn i søgestrengen? Du kan eventuelt lave en variabel hvor du overfører værdien:
Dim sogeord sogerord = Left(request.QueryString("soegeord"), Len(request.QueryString("soegeord")-1))
og så i din SQL kan du have: Fservices In ('" & Replace(soegeord), ",", "','") & "') ORDER BY Virksomhedsnavn ASC"
Som jeg ser det, så har du en ikke-optimal tabel (medlemmer), hvor du har et stort tekstfelt med alle aktuelle services, altså f.eks. 'service1, service3, service7'. Det er absolut ikke måden at gøre det på, hvis du er interesseret i en hurtig forespørgsel, for så er du som du selv er inde på nødt til at bruge LIKE funktionen. For det første er LIKE ikke under nogen omstændigheder optimal, da den ikke kan bruge indekser, men skal søge alle rows som opfylder evt. andre kriterier.
Det ville være meget bedre at flytte denne information til en selvstændig tabel som der så kan joines til (en row pr service). Så ville du kunne bruge IN instruktionen, som lorentsnv er inde på.
Hvis du derimod fastholder den nuværende struktur, er du nødt til at oprette en LIKE for hver funktion der søges på. Altså .. AND (Fservice LIKE '%Service1%' OR Fservice LIKE '%Service8%') Det kræver selvsagt noget mere kode. Det kunne f.eks. ligne dette:
sql = "SELECT * FROM medlemmer WHERE kommunenr =" & _ request.QueryString("kommunenr") If request.QueryString("soegeord") <> "" Then inp = request.QueryString("soegeord") Filter = " AND (Fservices LIKE '%" Do ' Søg efter et komma... pos = InStr(pos + 1, inp, ",") If pos > 0 Then If prevpos > 0 Then Filter = Filter & " OR fServices LIKE '%" End If Filter = Filter & Trim(Mid(inp, prevpos + 1, pos - prevpos - 1)) & "%'" prevpos = pos Else ' Ikke flere søgeord... Filter = Filter & " OR fServices LIKE '%" & _ Trim(Mid(inp, prevpos + 1, Len(inp) - prevpos)) & "%')" End If Loop Until pos = 0 sql = sql & Filter End If sql = sql & " ORDER BY Virksomhedsnavn ASC" medlemmer.source = sql
Okay, ved nærmere eftertanke kan det faktisk gøres meget lettere ved at bruge Replace instruktionen, som lorentsv også brugte:
If request.QueryString("soegeord") = "" Then medlemmer.Source = "SELECT * FROM medlemmer WHERE kommunenr =" & request.QueryString("kommunenr") & " ORDER BY Virksomhedsnavn ASC" Else medlemmer.Source = "SELECT * FROM medlemmer WHERE kommunenr =" & _ " AND (Fservices LIKE '%" & _ Replace(request.QueryString("kommunenr"), ",", " AND Fservices LIKE '%") & _ "%') ORDER BY Virksomhedsnavn ASC" End If
Argh, det der skal replaces er selvfølgelig søgeord:
If request.QueryString("soegeord") = "" Then medlemmer.Source = "SELECT * FROM medlemmer WHERE kommunenr =" & request.QueryString("kommunenr") & " ORDER BY Virksomhedsnavn ASC" Else medlemmer.Source = "SELECT * FROM medlemmer WHERE kommunenr =" & _ " AND (Fservices LIKE '%" & _ Replace(request.QueryString("soegeord"), ",", " AND Fservices LIKE '%") & _ "%') ORDER BY Virksomhedsnavn ASC" End If
Jeg kan nu se at der er et blankt tegn/space forran søgeord 2 og 3. Jeg tror derfor du skal have en space med i din søgestreng i Replace: ', '
Dim sogeord sogerord = Left(request.QueryString("soegeord"), Len(request.QueryString("soegeord")-1))
og så i din SQL kan du have: Fservices In ('" & Replace(soegeord), ", ", "','") & "') ORDER BY Virksomhedsnavn ASC"
Ellers er jeg ikke helt enig i hvad kjulius skriver.
Du ville bruge LIKE hvis din søgestreng indeholdt en substreng af feltet Fservices. Hvis din søgestreng indeholdt 'anders' kunne du søge frem alle forekomster af Fservices der 'anders' var en del af teksten ved følgende SQL:
SELECT * FROM medlemmer WHERE Fservices LIKE '%anders%'
Som jeg forstår det, får du en liste med søgeord returneret fra din QueryString, og du vil søge frem alle forekomster af Fservices der indeholder et af ordene i listen. Jeg går ud fra at de enkelte søgeord ikke kun er en substring af hvad du vil søge i i Fservices. I så fald har jeg misforstået, og så skal du bruge LIKE. Hvis din substring er 'sogeor1','sogeor2','sogeor3', og du har værdier i Fservices som er enten 'sogeor1' elle 'sogeor2' eller 'sogeor3', skal du bruge IN.
Det skyldes måske en skrivefejl jeg lavet i nat: Dim sogeord sogerord = Left(request.QueryString("soegeord"), Len(request.QueryString("soegeord")-1))
I linie 2 har jeg skrevet sogerord. Det skal være sogeord. Prøv med: Dim sogeord sogeord = Left(request.QueryString("soegeord"), Len(request.QueryString("soegeord")-1))
Set medlemmerne = Server.CreateObject("ADODB.Recordset") medlemmerne.ActiveConnection = MM_medlemsd_STRING if request.QueryString("soegeord") = "" then medlemmerne.Source = "SELECT * FROM medlemmer WHERE kommunenr =" & request.QueryString("kommunenr") & " ORDER BY Virksomhedsnavn ASC" else medlemmerne.Source = "SELECT * FROM medlemmer WHERE kommunenr =" & request.QueryString("kommunenr") & " AND Fservices In ('" & Replace(sogeord , ", ", "','") & "') ORDER BY Virksomhedsnavn ASC" end if medlemmerne.CursorType = 0 medlemmerne.CursorLocation = 2 medlemmerne.LockType = 1 medlemmerne.Open()
SQL setningen ser rigtig ud nu. Får du ingen resultater?
Forstår jeg dig rigtig når jeg forventer at Fservices direkte skal kunne sammenlignes med 'soegeord1' eller 'soegeord2' eller 'soegeord3', således at du eventelt også kunne få samme resultat med følgende SQL?
SELECT * FROM medlemmer WHERE kommunenr =727 AND (Fservices = 'soegeord1' or Fservices = 'soegeord2' or Fservices ='soegeord3') ORDER BY Virksomhedsnavn ASC
Nej ikke helt, grunden til at jeg brugte LIKE i starten var at hvert medlem har x antal søgeord i Fservices sepereret med komma! derfor kan dette vel ikke virke:
Det er helt fint. Hvis du får mange data i din base, skal du måske overveje at 'normailsere' din database, ved at du legger Fservices i en egen tabel som linkes til medlemstabellen. i Fservices vil du så have en record for hver søgeord. Dermed vil du kunne søge med IN-funktionen, og få en væsentlige bedre performance. Hvis din database ikke er så stor, har det måske ikke noget særlig betydning.
Sorry! det havde jeg helt glemt, troede faktisk jeg havde give points!
Synes godt om
Ny brugerNybegynder
Din løsning...
Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.