Avatar billede apo Praktikant
09. marts 2005 - 20:50 Der er 37 kommentarer og
1 løsning

SQL-sætninger

Hej.

Efter et par (af mig) dårligt formulerede spørgsmål prøver jeg igen :-)

Jeg har følgende SQL-sætning som indgår i en søgefunktion:

<%
'(...)
strSQL = "SELECT * FROM artikler WHERE "
strSQL = strSQL & " (Titel LIKE '%" & strTekst & "%')"
strSQL = strSQL & " OR (Blikfang LIKE '%" & strTekst & "%')"
strSQL = strSQL & " OR (Indhold LIKE '%" & strTekst & "%')"
'(...)
%>

Hvordan omskriver jeg ovenstående SQL så jeg kan give mine brugere muligheden for (i ét enkelt felt/input) at foretage en søgning på henholdsvis:

- Den eksakte frase
- Alle ordene
- Mindst ét af ordene?

Apo
Avatar billede arne_v Ekspert
09. marts 2005 - 21:29 #1
Det gør du ikke.

Du bliver nødt til at bruge flere SQL sætninger.

split søge teksten op i ord med Split funktionen

eksakt => 1 LIKE
alle ord => n LIKE med AND imellem
et ord => n LIKE med OR imellem
Avatar billede apo Praktikant
09. marts 2005 - 22:17 #2
Jeg regnede også med at det ville blive til flere SQL-sætninger ;-)

Mener du således?:

<%
        If Request.Form("avanceret") = "1" Then
      ' # DEN EKSAKTE FRASE
          strSoegeord = Split(strSoegeord," ")
          For i = LBound(strSoegeord) To UBound(strSoegeord)
              strSQL = "SELECT * FROM artikler WHERE "
              strSQL = strSQL & " (Titel 1 LIKE '%" & strSoegeord(i) & "%')"
              strSQL = strSQL & " OR (Blikfang 1 LIKE '%" & strSoegeord(i) & "%')"
              strSQL = strSQL & " OR (Indhold 1 LIKE '%" & strSoegeord(i) & "%')"
          Next
        ElseIf Request.Form("avanceret") = "2" Then
      ' # ALLE ORDENE
          strSoegeord = Split(strSoegeord," ")
          For i = LBound(strSoegeord) To UBound(strSoegeord)
              strSQL = "SELECT * FROM artikler WHERE "
              strSQL = strSQL & " (Titel n LIKE '%" & strSoegeord(i) & "%')"
              strSQL = strSQL & " AND (Blikfang n LIKE '%" & strSoegeord(i) & "%')"
              strSQL = strSQL & " AND (Indhold n LIKE '%" & strSoegeord(i) & "%')"
          Next
        Else
      ' # MINDST ÉT AF ORDENE
          strSoegeord = Split(strSoegeord," ")
          For i = LBound(strSoegeord) To UBound(strSoegeord)
              strSQL = "SELECT * FROM artikler WHERE "
              strSQL = strSQL & " (Titel n LIKE '%" & strSoegeord(i) & "%')"
              strSQL = strSQL & " OR (Blikfang n LIKE '%" & strSoegeord(i) & "%')"
              strSQL = strSQL & " OR (Indhold n LIKE '%" & strSoegeord(i) & "%')"
          Next
        End If
%>
(Note: Jeg har ændret strTekst til strSoegeord)

Apo
Avatar billede arne_v Ekspert
09. marts 2005 - 22:19 #3
Ikke helt
Avatar billede apo Praktikant
09. marts 2005 - 22:21 #4
Hvordan så?
Avatar billede arne_v Ekspert
09. marts 2005 - 22:21 #5
<%
        If Request.Form("avanceret") = "1" Then
      ' # DEN EKSAKTE FRASE
              strSQL = "SELECT * FROM artikler WHERE "
              strSQL = strSQL & " (Titel LIKE '%" & strSoegeord & "%')"
              strSQL = strSQL & " OR (Blikfang LIKE '%" & strSoegeord & "%')"
              strSQL = strSQL & " OR (Indhold LIKE '%" & strSoegeord & "%')"
        ElseIf Request.Form("avanceret") = "2" Then
      ' # ALLE ORDENE
          strSoegeord = Split(strSoegeord," ")
              strSQL = "SELECT * FROM artikler WHERE "
          For i = LBound(strSoegeord) To UBound(strSoegeord)
              strSQL = strSQL & " (Titel LIKE '%" & strSoegeord(i) & "%')"
              strSQL = strSQL & " AND (Blikfang LIKE '%" & strSoegeord(i) & "%')"
              strSQL = strSQL & " AND (Indhold LIKE '%" & strSoegeord(i) & "%')"
          Next
        Else
      ' # MINDST ÉT AF ORDENE
          strSoegeord = Split(strSoegeord," ")
              strSQL = "SELECT * FROM artikler WHERE "
          For i = LBound(strSoegeord) To UBound(strSoegeord)
              strSQL = strSQL & " (Titel LIKE '%" & strSoegeord(i) & "%')"
              strSQL = strSQL & " OR (Blikfang LIKE '%" & strSoegeord(i) & "%')"
              strSQL = strSQL & " OR (Indhold LIKE '%" & strSoegeord(i) & "%')"
          Next
        End If
%>

ser mere rigtig ud
Avatar billede arne_v Ekspert
09. marts 2005 - 22:23 #6
Hm.

2 og 3 sidste mangler faktisk yderligere en OR mellem hvert gennemløb af løkken.
Avatar billede apo Praktikant
09. marts 2005 - 22:30 #7
Arne > Jeg har først tid til at kigge på det i morgen aften (jeg havde ikke regnet med svar så hurtigt ;-) ).

Men hvordan mangler der yderligere en OR mellem hvert gennemløb?

Apo
Avatar billede arne_v Ekspert
09. marts 2005 - 22:37 #8
ElseIf Request.Form("avanceret") = "2" Then
      ' # ALLE ORDENE
          strSoegeord = Split(strSoegeord," ")
              strSQL = "SELECT * FROM artikler WHERE "
          For i = LBound(strSoegeord) To UBound(strSoegeord)
              If i > LBound(strSoegeord) Then
                strSQL = strSQL & " OR "
              End If
              strSQL = strSQL & " ((Titel LIKE '%" & strSoegeord(i) & "%')"
              strSQL = strSQL & " AND (Blikfang LIKE '%" & strSoegeord(i) & "%')"
              strSQL = strSQL & " AND (Indhold LIKE '%" & strSoegeord(i) & "%'))"
          Next
        Else
      ' # MINDST ÉT AF ORDENE
          strSoegeord = Split(strSoegeord," ")
              strSQL = "SELECT * FROM artikler WHERE "
          For i = LBound(strSoegeord) To UBound(strSoegeord)
              If i > LBound(strSoegeord) Then
                strSQL = strSQL & " OR "
              End If
              strSQL = strSQL & " ((Titel LIKE '%" & strSoegeord(i) & "%')"
              strSQL = strSQL & " OR (Blikfang LIKE '%" & strSoegeord(i) & "%')"
              strSQL = strSQL & " OR (Indhold LIKE '%" & strSoegeord(i) & "%'))"
          Next
        End If
Avatar billede apo Praktikant
10. marts 2005 - 20:56 #9
Så har jeg kigget på det, men jeg kæmper med følgende fejl:

Microsoft VBScript runtime error '800a000d'
Type mismatch
/Soeg.asp, line 237

Det virker tilsyneladende som det skal, når jeg fjerner følgende:

<%
    ' # TÆLLER ANTAL FUNDNE RESULTATER
        Set rs2 = myConn.Execute("SELECT COUNT(*) AS Resultater_Count FROM artikler WHERE (Titel LIKE '%" & strSoegeord & "%' OR Blikfang LIKE '%" & strSoegeord & "%' OR Indhold LIKE '%" & strSoegeord & "%')")
        If rs2("Resultater_Count") = 1 Then
          strResultater = "resultat."
        ElseIf rs2("Resultater_Count") > 1 Then
          strResultater = "resultater."
        Else
          strResultater = "resultater."
        End if
%>

Ovenstående har virket hidtil, men skaber åbenbart en konflikt når jeg bruger de nye SQL-sætninger. Kan du se hvor fejlen er/hvad der skal rettes?

Apo
Avatar billede arne_v Ekspert
10. marts 2005 - 20:58 #10
hvilken linier 237 ?
Avatar billede apo Praktikant
10. marts 2005 - 21:05 #11
Linje 237:

Set rs2 = myConn.Execute("SELECT COUNT(*) AS Resultater_Count FROM artikler WHERE (Titel LIKE '%" & strSoegeord & "%' OR Blikfang LIKE '%" & strSoegeord & "%' OR Indhold LIKE '%" & strSoegeord & "%')")
Avatar billede arne_v Ekspert
10. marts 2005 - 21:06 #12
er strSoegeord en string eller et array påd et sted i koden ?
Avatar billede apo Praktikant
10. marts 2005 - 21:10 #13
strSoegeord er en string
Avatar billede apo Praktikant
10. marts 2005 - 21:13 #14
strSoegeord overføres fra inputfeltet via en QueryString (hvis du kan bruge det til noget)
Avatar billede apo Praktikant
10. marts 2005 - 21:24 #15
Alt foretages på den samme side (Soeg.asp)

Hvis det hjælper dig bedre, ser den øverste del af koden (søgeresultater) således ud:

<%
' # INDSÆTTER SØGERESULTATER -------------------------------------------------------------------------------------------------------------

    If Request.QueryString("Soegeord") <> "" Then

    ' # HENTER SØGEORD
        strSoegeord = Trim(Request.QueryString("Soegeord"))

        If Request.QueryString ("Side") = "" Then
          Response.Redirect "Soeg.asp?Soegeord=" & strSoegeord & "&Side=1"
        End If

'        If Len(strSoegeord) = 0 Then
      ' # HVIS DER IKKE ER SKREVET I FELTET
'          Response.Clear
'          Response.Redirect("Soeg.asp")
'        Else
      ' # HVIS DER ER SKREVET I FELTET
'          strSoegeord = Replace(strSoegeord,"'","''")
'        End If

    ' # SKABER DNSLESS FORBINDELSE TIL DATABASEN
        strDSN = "DRIVER={Microsoft Access Driver (*.mdb)};DBQ=d:\www\db\artikler.mdb"
        Set myConn = Server.CreateObject("ADODB.Connection")
        myConn.Open strDSN

    ' # INDSÆTTER PAGING-FUNKTION
        intPage = Request("Side")
        If isNumeric(intPage) = False Or intPage < 1 Then
          intPage = 1
        End If

    ' # ÅBNER RECORDSETTET
        Set rs = Server.CreateObject("ADODB.RecordSet")

        strAvanceret = Request.Form("avanceret")
        If strAvanceret = "1" Then
      ' # SØGER PÅ DEN EKSAKTE FRASE
          strSQL = "SELECT * FROM artikler WHERE "
          strSQL = strSQL & " (Titel LIKE '%" & strSoegeord & "%')"
          strSQL = strSQL & " OR (Blikfang LIKE '%" & strSoegeord & "%')"
          strSQL = strSQL & " OR (Indhold LIKE '%" & strSoegeord & "%')"
        ElseIf strAvanceret = "2" Then
      ' # SØGER PÅ ALLE ORDENE
          strSoegeord = Split(strSoegeord," ")
          strSQL = "SELECT * FROM artikler WHERE "
          For i = LBound(strSoegeord) To UBound(strSoegeord)
              If i > LBound(strSoegeord) Then
                strSQL = strSQL & " OR "
              End If
              strSQL = strSQL & " ((Titel LIKE '%" & strSoegeord(i) & "%')"
              strSQL = strSQL & " AND (Blikfang LIKE '%" & strSoegeord(i) & "%')"
              strSQL = strSQL & " AND (Indhold LIKE '%" & strSoegeord(i) & "%'))"
          Next
        Else
      ' # SØGER PÅ MINDST ÉT AF ORDENE
          strSoegeord = Split(strSoegeord," ")
          strSQL = "SELECT * FROM artikler WHERE "
          For i = LBound(strSoegeord) To UBound(strSoegeord)
              If i > LBound(strSoegeord) Then
                strSQL = strSQL & " OR "
              End If
              strSQL = strSQL & " ((Titel LIKE '%" & strSoegeord(i) & "%')"
              strSQL = strSQL & " OR (Blikfang LIKE '%" & strSoegeord(i) & "%')"
              strSQL = strSQL & " OR (Indhold LIKE '%" & strSoegeord(i) & "%'))"
          Next
        End If

    ' # TÆLLER ANTAL FUNDNE RESULTATER
        Set rs2 = myConn.Execute("SELECT COUNT(*) AS Resultater_Count FROM artikler WHERE (Titel LIKE '%" & strSoegeord & "%' OR Blikfang LIKE '%" & strSoegeord & "%' OR Indhold LIKE '%" & strSoegeord & "%')")
        If rs2("Resultater_Count") = 1 Then
          strResultater = "resultat."
        ElseIf rs2("Resultater_Count") > 1 Then
          strResultater = "resultater."
        Else
          strResultater = "resultater."
        End if

    ' # FORKORTER SØGETEKST, HVIS OVER 25 TEGN
        If Len(Request.QueryString("Soegeord")) <= 25 Then
          strSoegeord2 = Request.QueryString("Soegeord")
        Else
          strSoegeord2 = Left(Request.QueryString("Soegeord"),25) & "..."
        End If
%>

Apo
Avatar billede arne_v Ekspert
10. marts 2005 - 22:50 #16
Hvis den her:

strSoegeord = Split(strSoegeord," ")

udføres så er strSoegeord jo etarray af String
Avatar billede apo Praktikant
11. marts 2005 - 17:54 #17
Okay, så er strSoegeord et array... Men hvad skal jeg ændre i tællefunktionen (jeg er ikke helt med)?
Avatar billede apo Praktikant
11. marts 2005 - 20:24 #18
Opgaven har udviklet sig lidt mere end først antaget, så jeg forhøjer pointene :-)
Avatar billede arne_v Ekspert
11. marts 2005 - 21:31 #19
Jeg forstår slet ikke logikken.

Skal den query ikke bruge samme betingelser som den strSQL du opbygger ?
Avatar billede apo Praktikant
11. marts 2005 - 22:19 #20
Jo, det skal den. Formålet er at vise brugeren hvor mange match/artikler, søgningen resulterede i.

Jeg ved dog ikke hvordan jeg skal ændre tælleren for at den virker med de nye SQL-sætninger...
Avatar billede arne_v Ekspert
11. marts 2005 - 22:26 #21
Prøv noget a la dette:

<%
' # INDSÆTTER SØGERESULTATER -------------------------------------------------------------------------------------------------------------

    If Request.QueryString("Soegeord") <> "" Then

    ' # HENTER SØGEORD
        strSoegeord = Trim(Request.QueryString("Soegeord"))

        If Request.QueryString ("Side") = "" Then
          Response.Redirect "Soeg.asp?Soegeord=" & strSoegeord & "&Side=1"
        End If

'        If Len(strSoegeord) = 0 Then
      ' # HVIS DER IKKE ER SKREVET I FELTET
'          Response.Clear
'          Response.Redirect("Soeg.asp")
'        Else
      ' # HVIS DER ER SKREVET I FELTET
'          strSoegeord = Replace(strSoegeord,"'","''")
'        End If

    ' # SKABER DNSLESS FORBINDELSE TIL DATABASEN
        strDSN = "DRIVER={Microsoft Access Driver (*.mdb)};DBQ=d:\www\db\artikler.mdb"
        Set myConn = Server.CreateObject("ADODB.Connection")
        myConn.Open strDSN

    ' # INDSÆTTER PAGING-FUNKTION
        intPage = Request("Side")
        If isNumeric(intPage) = False Or intPage < 1 Then
          intPage = 1
        End If

    ' # ÅBNER RECORDSETTET
        Set rs = Server.CreateObject("ADODB.RecordSet")

        strAvanceret = Request.Form("avanceret")
        If strAvanceret = "1" Then
      ' # SØGER PÅ DEN EKSAKTE FRASE
          strSQL = " WHERE "
          strSQL = strSQL & " (Titel LIKE '%" & strSoegeord & "%')"
          strSQL = strSQL & " OR (Blikfang LIKE '%" & strSoegeord & "%')"
          strSQL = strSQL & " OR (Indhold LIKE '%" & strSoegeord & "%')"
        ElseIf strAvanceret = "2" Then
      ' # SØGER PÅ ALLE ORDENE
          strSoegeord = Split(strSoegeord," ")
          strSQL = " WHERE "
          For i = LBound(strSoegeord) To UBound(strSoegeord)
              If i > LBound(strSoegeord) Then
                strSQL = strSQL & " OR "
              End If
              strSQL = strSQL & " ((Titel LIKE '%" & strSoegeord(i) & "%')"
              strSQL = strSQL & " AND (Blikfang LIKE '%" & strSoegeord(i) & "%')"
              strSQL = strSQL & " AND (Indhold LIKE '%" & strSoegeord(i) & "%'))"
          Next
        Else
      ' # SØGER PÅ MINDST ÉT AF ORDENE
          strSoegeord = Split(strSoegeord," ")
          strSQL = " WHERE "
          For i = LBound(strSoegeord) To UBound(strSoegeord)
              If i > LBound(strSoegeord) Then
                strSQL = strSQL & " OR "
              End If
              strSQL = strSQL & " ((Titel LIKE '%" & strSoegeord(i) & "%')"
              strSQL = strSQL & " OR (Blikfang LIKE '%" & strSoegeord(i) & "%')"
              strSQL = strSQL & " OR (Indhold LIKE '%" & strSoegeord(i) & "%'))"
          Next
        End If
      strSQLstar = "SELECT * FROM artikler" & strSQL

    ' # TÆLLER ANTAL FUNDNE RESULTATER
        strSQLcount = "SELECT COUNT(*) AS Resultater_Count FROM artikler" & strSQL
        Set rs2 = myConn.Execute(strSQLcount)
        If rs2("Resultater_Count") = 1 Then
          strResultater = "resultat."
        ElseIf rs2("Resultater_Count") > 1 Then
          strResultater = "resultater."
        Else
          strResultater = "resultater."
        End if

    ' # FORKORTER SØGETEKST, HVIS OVER 25 TEGN
        If Len(Request.QueryString("Soegeord")) <= 25 Then
          strSoegeord2 = Request.QueryString("Soegeord")
        Else
          strSoegeord2 = Left(Request.QueryString("Soegeord"),25) & "..."
        End If
%>
Avatar billede apo Praktikant
11. marts 2005 - 22:39 #22
Det giver denne fejl:

Microsoft OLE DB Provider for ODBC Drivers error '80040e21'
ODBC driver does not support the requested properties.
/Soeg.asp, line 323

Linje 323 er denne: rs.Open strSQL, myConn, 1

(en del af en paging-funktion...)
Avatar billede arne_v Ekspert
11. marts 2005 - 22:47 #23
Du skal nok bruge:

rs.Open strSQLall, myConn, 1

der
Avatar billede apo Praktikant
11. marts 2005 - 22:51 #24
Endnu en fejl:

ADODB.Recordset error '800a0bb9'
Arguments are of the wrong type, are out of acceptable range, or are in conflict with one another.
/Soeg.asp, line 323
Avatar billede arne_v Ekspert
11. marts 2005 - 22:54 #25
Så skal du vist lige have checket indholdet af strSQLall !

der angler nok et mellemrum eller en en ' for meget eller sådan noget
Avatar billede apo Praktikant
11. marts 2005 - 23:00 #26
Kan det passe at sætningen:
rs.Open strSQLall, myConn, 1

Skal hedde:
rs.Open strSQLstar, myConn, 1

?

(Efter udskiftning af sætningen kommer resultatet frem - Ingen fejlmeddelelser)
Avatar billede arne_v Ekspert
11. marts 2005 - 23:02 #27
ja for pokker

jeg tænkte først på at kalde den strSQLall emn ombestemte mig så

sorry
Avatar billede apo Praktikant
11. marts 2005 - 23:08 #28
Helt i orden :-)

Jeg har lige endnu et prob; Jeg får en fejlmeddelelse når jeg søger på enkelte bogstaver... Der står at søgningen resulterede i 5 resultater (på f.eks. bogstavet 'h'), men der hvor artiklerne skal vises får jeg følgende fejl:

Microsoft VBScript runtime error '800a000d'
Type mismatch
/Soeg.asp, line 402

Linje 402: Response.Write "<a href=""Soeg.asp?Soegeord=" & strSoegeord & "&Side=" & intNum & """ class=""link4"">" & intNum & "</a> "
Avatar billede arne_v Ekspert
11. marts 2005 - 23:13 #29
er det ikke samme problem - at strSoegeord nu er blevet til et array ?
Avatar billede apo Praktikant
11. marts 2005 - 23:19 #30
Hmm... Skal paging-linjerne så omskrives, og hvis, hvordan så?

Linjen stammer fra den sidste del af søgefunktionen, der indsætter paging på resultatsiderne.
Avatar billede arne_v Ekspert
11. marts 2005 - 23:23 #31
Prøv:

Response.Write "<a href=""Soeg.asp?Soegeord=" & Trim(Request.QueryString("Soegeord"))
& "&Side=" & intNum & " class=""link4"">" & intNum & "</a> "
Avatar billede apo Praktikant
11. marts 2005 - 23:34 #32
Det var åbenbart det der skulle til... Nu får jeg tilsyneladende ikke flere fejlmeddelelser :-)

Afsluttende spørgsmål:

Jeg synes ikke at der er synlig forskel på de 3 søgemetoder (resultaterne er de samme). Fungerer koden som den skal?
Avatar billede apo Praktikant
11. marts 2005 - 23:35 #33
koden = SQLen
Avatar billede apo Praktikant
11. marts 2005 - 23:54 #34
Ahh... Jeg får ikke værdien af 'avanceret' med i QueryStringen, så er det jo klart at resultaterne er de samme :-/

Har du et bud på hvordan jeg får smidt værdien af både Soegeord og Avanceret op i QueryStringen? Det her virker tilsyneladende ikke:

<form style="display: inline;" method="get" action="Soeg.asp?Soegeord=<%=Request.Form("soegeord")%>&amp;Avanceret=<%=Request.Form("avanceret")%>&amp;Side=1">
Avatar billede apo Praktikant
11. marts 2005 - 23:55 #35
... Og smid lige et svar, så du kan få dine points :-)
Avatar billede arne_v Ekspert
12. marts 2005 - 08:49 #36
Response.Write "<a href=""Soeg.asp?Soegeord=" & Trim(Request.QueryString("Soegeord"))
& "&Avanceret=" & Request.Form("avanceret") & "&Side=" & intNum & " class=""link4"">" & intNum & "</a> "

måske
Avatar billede arne_v Ekspert
12. marts 2005 - 08:49 #37
og et svar
Avatar billede apo Praktikant
12. marts 2005 - 12:06 #38
Nu var det i selve formularen jeg havde problemet ;-)

Tilsyneladende fandt jeg selv en måde at løse problemet på, og det ser ud til at fungere efter hensigten.

Arne, jeg siger mange tak for din tid og hjælp (og ikke mindst din tålmodighed!). Der er points på vej i din retning :-)

// Lukker

Apo
Avatar billede Ny bruger Nybegynder

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.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester