webForumDet fria alternativet

Sökfunktion som söker i flera olika fält... Kört fast.

ASP

15 svar · 764 visningar · startad av Donatello

Medlem sedan jan. 2005108 inlägg
Frågan#1

Hej på er. :)

Har knåpat ihop en sökfunktion som, i mina ögon, borde fungera hur bra som helst. Guess what... Det gör den inte. x(

Skulle någon smart människa kunna ta en titt på koden nedan och försöka klura ut varför jag får följande felmeddelande:

ADODB.Command error '800a0e7c' 

Parameter object is improperly defined. Inconsistent or incomplete information was provided. 

/search/process.asp, line 53

Problemet kommer på cmd.execute raden...

<%option explicit%>
<!-- #include virtual = "/builder.asp" -->
<%
dim Search, wri, Conn, RecSet, cmd, sqlstmt, ArrSearch, item, count, ArrParameters(), ParamCount, i, checkcount
Search = Request("search")
IF Search = empty THEN Response.Redirect "/?url=/search/default.asp"

wri = "<p><b>Sökning efter ""<i>"& Server.htmlencode(search) &"</i>"".</b></p>"

ArrSearch = Split(Search, " ", -1, 1)

count = 0
For Each item In ArrSearch
  ArrSearch(count) = Trim(ArrSearch(count))
  count = count+1
Next

sqlstmt = "SELECT * FROM annonser WHERE titel_ LIKE '%?%' OR namn_ LIKE '%?%' OR telefon_ LIKE '%?%' OR epost_ LIKE '%?%' OR innehall_ LIKE '%?%' OR hemsida_ LIKE '%?%'"
ParamCount = 6
Redim ArrParameters(ParamCount)
For i = 0 to 5
  ArrParameters(i) = ArrSearch(0)
Next
checkcount = 1

Do Until checkcount = count
  sqlstmt = "SELECT * FROM annonser WHERE titel_ LIKE '%?%' OR namn_ LIKE '%?%' OR telefon_ LIKE '%?%' OR epost_ LIKE '%?%' OR innehall_ LIKE '%?%' OR hemsida_ LIKE '%?%' AND ID IN ("& sqlstmt &")"
  ParamCount = ParamCount +6
  Redim Preserve ArrParameters(ParamCount)
  For i = (ParamCount -6) to (ParamCount -1)
    ArrParameters(i) = ArrSearch(checkcount)
  Next
  checkcount = checkcount +1
Loop

Set Conn = Server.CreateObject("ADODB.Connection")
Conn.open "PROVIDER=MICROSOFT.JET.OLEDB.4.0;DATA SOURCE=asdf.mdb;"
Set cmd = server.createobject("adodb.command")
cmd.activeConnection = Conn
cmd.CommandText = sqlstmt

Set RecSet = cmd.Execute(, ArrParameters)

IF RecSet.EOF THEN
  wri = wri & "<p>Inga träffar.</p>"
ELSE
  Do Until RecSet.EOF
    wri = wri & builder(RecSet("ID"))
    RecSet.MoveNext
  Loop
END IF

RecSet.Close
Set RecSet = Nothing
Set cmd = Nothing
Conn.Close
Set Conn = Nothing

Response.Write wri
%>

Är tacksam för all hjälp jag kan få. Har försökt i flera dagar nu utan att lyckas.

Medlem sedan juni 20031 837 inlägg
#2

Vilken rad är rad 53?

Vad tjänar du på att stoppa SQL-satser i varandra flera gånger?
kommer ju att bli en gigantiskt SQL-fråga.

Medlem sedan okt. 20041 556 inlägg
#3

Rad 53 är väl denna: Set RecSet = cmd.Execute(, ArrParameters)

Men är inte ArrParameters en array av något slag?

Medlem sedan juni 20031 837 inlägg
#4

Måste man inte skicka med den första parametern?

Medlem sedan jan. 2005108 inlägg
#5

Vad tjänar du på att stoppa SQL-satser i varandra flera gånger?
kommer ju att bli en gigantiskt SQL-fråga.

Det var enda sättet jag kom på... Jag splittar upp orden i söksträngen, så om man söker på ex.vis "äldreomsorg stockholm" så ska man få träff om äldreomsorg finns i exvis titel_ och stockholm finns text_. Första frågan träffar alla rader i databasen där första ordet finns, andra frågan träffar alla rader från första frågan där andra ordet finns osv.

Vilken rad är rad 53?

Rad 53 är: Set RecSet = cmd.Execute(, ArrParameters)

Men är inte ArrParameters en array av något slag?

ArrParameters är en array som innehåller sökorden enligt följande: ArrParameters(0-5) = sökord 1, ArrParameters(6-11) = sökord 2 osv (eftersom varje sökord testas i sex olika kolumner).

Måste man inte skicka med den första parametern?

Inte i detta fallet. Har använt mig av denna metod tidigare.

Lösningar...? *smådesperat* :OO

Medlem sedan okt. 20041 556 inlägg
#6

skriv ut dina parametervärden:

Response.Write ArrParameters
Response.end()
Set RecSet = cmd.Execute(, ArrParameters)

Så ser du om det ser rätt ut.

Medlem sedan jan. 2005108 inlägg
#7

skriv ut dina parametervärden

Testat det...

count = 0
Do Until count = ParamCount
  Response.Write ArrParameters(count) & "<br>"
  count = count +1
Loop
Response.end()

Söker jag på exemplet "äldreomsorg stockholm" blir resultatet:

äldreomsorg
äldreomsorg
äldreomsorg
äldreomsorg
äldreomsorg
äldreomsorg
stockholm
stockholm
stockholm
stockholm
stockholm
stockholm

Frustrerande... :OO

Fler idéer?

Medlem sedan okt. 20041 556 inlägg
#8

Måste bara fråga: Vad är det du vill göra?
Om man söker på ex.: äldreomsorg stockholm
Så vill du att äldreomsorg och stockholm skall hittas i alla fält?
Jag skulle nog skippa den parameteriserade frågan och bygga ihop sql:en med en for-sats istället. Se bara till att ta bort "farliga" tecken.

Medlem sedan juni 20031 837 inlägg
#9

Jag personligen hade skrivit om SQL-satsen så den blir i stil med:

sqlstmt = "SELECT * FROM annonser WHERE 1=1"

Do Until checkcount = count
  sqlstmt = sqlstmt & " OR titel_ LIKE '%"&ArrSearch(checkcount)&"%' OR namn_ LIKE '%"&ArrSearch(checkcount)&"%' OR telefon_ LIKE '%?%' OR epost_ LIKE '%?%' OR innehall_ LIKE '%"&ArrSearch(checkcount)&"%' OR hemsida_ LIKE '%"&ArrSearch(checkcount)&"%'"
Loop

då får du en enda SQL-sats, blir ju i och för sig längre ju fler ord man skickar in.
kommer kanske inte att lösa ditt problem men enligt mig ser det snyggare ut.
Skulle tro att det även blir mer lättlästliget. vet dock inte hur prestandan påverkas, tycker inte den borde bli sämre.

Medlem sedan okt. 20041 556 inlägg
#10
ArrSearch = Split(replace(Search,"'","''"), " ") '/r
sql = "SELECT * FROM annonser WHERE ("
andor = "AND" 'eller "OR"

For i = 0 to ubound(ArrSearch)
	sql = sql & "(titel_ LIKE '%"& ArrSearch(i) &"%' OR namn_ LIKE '%"& ArrSearch(i) &"%' OR "
	sql = sql & "telefon_ LIKE '%"& ArrSearch(i) &"%' OR epost_ LIKE '%"& ArrSearch(i) &"%' OR "
	sql = sql & "innehall_ LIKE '%"& ArrSearch(i) &"%' OR hemsida_ LIKE '%"& ArrSearch(i) &"%') " & andor & " "
Next

sql = left(sql, len(sql) - 4) & ")"

Set RecSet = cmd.Execute(sql)
Medlem sedan jan. 2005108 inlägg
#11

Måste bara fråga: Vad är det du vill göra?
Om man söker på ex.: äldreomsorg stockholm
Så vill du att äldreomsorg och stockholm skall hittas i alla fält?

Jag vill att äldreomsorg ska hittas i något av fälten och stockholm i något av fälten. Inte nödvändigtvis samma, men båda måste finnas nånstans.

Jag skulle nog skippa den parameteriserade frågan och bygga ihop sql:en med en for-sats istället. Se bara till att ta bort "farliga" tecken.

Mixtra med söksträngen då, menar du? Köra några replacear... Problemet då blir ju att om det finns "farliga" tecken i databasen (vilket det gör på några ställen), så blir ju inte sökningen efter dessa korrekt... Eller..? :l

Medlem sedan okt. 20041 556 inlägg
#12

Se bara till att göra en replace på apostrofer.
ArrSearch = Split(replace(Search,"'","''"), " ")

Medlem sedan jan. 2005108 inlägg
#13

sqlstmt = "SELECT * FROM annonser WHERE 1=1"

Do Until checkcount = count
sqlstmt = sqlstmt & " OR titel_ LIKE '%"&ArrSearch(checkcount)&"%' OR namn_ LIKE '%"&ArrSearch(checkcount)&"%' OR telefon_ LIKE '%?%' OR epost_ LIKE '%?%' OR innehall_ LIKE '%"&ArrSearch(checkcount)&"%' OR hemsida_ LIKE '%"&ArrSearch(checkcount)&"%'"
Loop

Med denna kod får jag ju även träffar där bara ett av orden finns med, eftersom man bara använder sig av OR.......

Medlem sedan jan. 2005108 inlägg
#14

Se bara till att göra en replace på apostrofer.
ArrSearch = Split(replace(Search,"'","''"), " ")

Har lärt mig att enbart detta inte skyddar mot injections... men jag kan ha fel... Har bara hållit mig till parameteriserade frågor.

Ska testa lite nu.. Återkommer senare. :)

Medlem sedan okt. 20041 556 inlägg
#15

Det beror på vilken databas du jobbar med.

Medlem sedan jan. 2005108 inlägg
#16

Travoni skrev:

Det beror på vilken databas du jobbar med.

Access 2000...

268 ms totalt · 4 externa anrop · v20260731065814-full.6fe65c25
128 ms — deklarationer (db)
0 ms — hämta statistik (cache)
136 ms — hämta tråd, inlägg och bilagor (db)
129 ms — ändringar (db)