09. september 2007 - 23:40Der er
55 kommentarer og 2 løsninger
Relevans sortering af udtræk fra database
Jeg mangler at de fundne poster sorteres efter relevans (De ord som søges efter hvis de totalt set findes 5 steder i atabasen skal de komme før en post hvor 1 eller flere af ordrene kun kommer ialt 4 gange)
str = "(Beskriv100 like '%"& searchArr(0) &"%' or Beskriv like '%"& searchArr(0) &"%' or Fabrikat like '%"& searchArr(0) &"%' OR VareNr like '%"& searchArr(0) &"%') " for f=1 to ubound(searchArr) str = str & " or (Beskriv100 like '%"& searchArr(f) &"%' or Beskriv like '%"& searchArr(f) &"%' OR Fabrikat like '%"& searchArr(0) &"%' OR VareNr like '%"& searchArr(f) &"%') " next
Kan man i SQL stregen få optællingen med og hvordan? P.S: Det er en Access database det kører i P.T. men overvejer at skifte til en MySQL istedet.
Under alle omstændigheder bliver du nok nødt til at oprette en funktion i din access database. Ellers vil du ikke kunne sortere på værdien. Det ser ud til, at det er noget ASP kode du udfører. For at oprette funktioen er du nødt til at have direkte adgang til databasen, da du skal placere funktionen i et modul.
Men ellers er det for så vidt ligetil. Du opretter en funktion med to parametre (dit databasefelt og dit søgekriterie) og en returværdi med antallet af fundne forekomster.
I din SQL bruger du funktionen som enhver anden funktion:
SELECT dinFunktion(ditFelt1, ditSøgekriterie) + dinFunktion(ditFelt2, ditSøgekriterie) AS Forekomster FROM dinTabel WHERE ... ORDER BY Forekomster DESC
Den skal tælle alle forekomster også selvom de optræder flere gange i samme felt. Jeg kan ikke helt finde ud af hvad det er for noget funktion der her tænkes på? Men jo det er ASP jeg har lavet siden i, men er desværre ikke den største haj til det :-)
I SQL kan man lave nye funktioner (de kaldes UDF (User Defined Function)).
I Access placerer man disse UDF i et modul i selve databasen. At placere den der er, så vidt jeg ved, ikke muligt fra ASP. Men du har vel en lokal kopi af din database, ellers må du downloade den fra dit site, oprette modulet og placere funktionen i det. Herefter kan du uploade databasen igen.
Din funktion kunne f.eks. se sådan ud:
Public Function Forekomster(dbFelt As Variant, SearchFor As String) As Integer Dim SearchArr As Variant Dim f As Integer Dim spos As Integer Dim pos As Integer If IsNull(dbFelt) Or dbFelt = "" Or SearchFor = "" Then Exit Function SearchArr = Split(SearchFor) For f = 0 To UBound(SearchArr) spos = 1 Do pos = InStr(spos, dbFelt, Trim(SearchArr(f))) If pos > 0 Then spos = pos + 1 Forekomster = Forekomster + 1 End If Loop Until pos = 0 Next End Function
Prøv at indsætte den i et modul i databasen. Du vil herefter (efter at have uploaded databasen igen) kunne bruge den i din SQL:
strSQL = "SELECT Forekomster(Beskriv100, '" & Search & ')+Forekomster(Beskriv, '" & Search & "')+Forekomster(Fabrikat, '" & Search & "')+Forekomster(Varenr, '" & Search & "') AS ForekomsterTotalt, Varenr, Beskriv100, Beskriv, Fabrikat " strSQL = strSQL & "FROM dinTabel " strSQL = strSQL & "WHERE " For f = 0 to Ubound(SearchArr) strSQL = strSQL & " or (Beskriv100 like '%"& searchArr(f) &"%' or Beskriv like '%"& searchArr(f) &"%' OR Fabrikat like '%"& searchArr(0) &"%' OR VareNr like '%"& searchArr(f) &"%') " Next strSQL = "ORDER BY Forekomster(Beskriv100, '" & Search & ')+Forekomster(Beskriv, '" & Search & "')+Forekomster(Fabrikat, '" & Search & "')+Forekomster(Varenr, '" & Search & ') DESC"
Uden at lægge hovedet på blokken, vil jeg tro, at det er hvad der skal til. :-)
Dette kan jeg ikke helt finde ud fa hvordan jeg skal gøre, nu har jeg snart forsøgt alt hvad jeg troede det kunne være men aner faktisk ikke rigtigt noget om databaser på denne måde?
Okay, når du har hentet din Access fra din webserver, ligger der nu en lokal kopi på din computer. Herefter er proceduren:
1. Åbn databasen 2. Ude til venstre klikker du på punktet Moduler 3. Opret et nyt modul ved at klikke på "Ny" på menuen lige ovenfor (hvis der i forvejen findes et modul, kan du også åbne dette ved at dobbeltklikke på det). 4. Der bliver nu vist en kodeside, hvor du kan paste funktionskoden ind (VBA koden fra min kommentar). 5. Luk nu databasen - du vil blive spurgt om du vil gemme det nye modul, det siger du ja til 6. Evt. kan du give modulet et sigende navn, når du bliver spurgt. 7. Du uploader databasen igen.
Du har nu adgang til funktionen fra SQL forespørgsler i din ASP kode.
Hold fast hvor kan man stirre sig blind hehe den var jo lige først for i vinduet ehhe
Nå men nu er koden sat ind og jeg har sat et par manglende " men der er lidt problemer med sorteringen det er ikke den med flest sammenligninger den viser først?
Jeg har taget koden som du har skrevet den heroppe fuldt ud dog tiljer 3 stk " da den ellersd felmeldte kodden men så accepter den koden og viser søgningen udfra det du har skrevet herover, men den viser dem bare ikke i den rækkefølge?
Hmmm... Det er jo den funktion du oprettede i modulet. Efter at du havde indsat funktionskoden, udførte du så også punkt 7 i min lille spiseseddel, at uploade databasen til dit site igen?
Skulle der være nogle linier i toppen af modulet elelr som afslutning eller noget, for da jeg oprettede en ny lavede den selv 2 linier, dem fjernede jeg igen, men jeg har også prøvet at sætte dem ind øverst igen, men det giver samme fejl...
Det burde ikke betyde noget med de to linier. I dit modul er der da nøjagtig den kode, jeg angav i 10/09-2007 23:48:10 - altså koden fra-og-med Public Function og til-og-med End Function?
Så burde funktionen også hedde Forekomster. Hmmm...
Prøv at kalde funktionen fra det direkte vindue nederst (Immediate window):
?Forekomster("Den lille dreng satte sig på sin lille cykel og drønede afsted", "lille dreng")
Giver det en fejl, eller returnerer funktionen en værdi (som i dette tilfælde burde blive 3)?
Det betyder, at Access er forvirret. Du har åbenbart også navngivet modulet Forekomster. Det var ikke så heldigt, da der jo så er to objekter med samme navn.
Det er modulet du har omdøbt og ikke funktionen, ikke også?
Hvis det er funktionen du har omdøbt, skal forespørgslen ændres tilsvarende. Så jeg vil mene, at det i så fald er nemmere at rette funktionsnavnet tilbage og ændre navnet på modulet. Marker modulnavnet, højreklik på det og vælg Omdøb.
Okay, nej split var vist ikke indført dengang den var moderne. :-)
Men så må vi prøve at lave funktionen selv. :-)
Her er en lille rutine som laver det samme. Den er lidt mere primitiv end den split vi kender, men det er kun de meget lidt brugte 3. og 4. parametre den ikke tager højde for.
Prøv at indsætte denne funktion i modulet sammen med funktionen Forekomster:
Public Function Split(inString As String, Optional strDelim As Variant) As Variant Dim strDelimiter As String Dim strString As String Dim intOrd As Integer Dim intStartPos As Integer Dim intPos As Integer ReDim arrOrd(0 To 99) As String If IsMissing(strDelim) = True Or (VarType(strDelim) <> vbString And VarType(strDelim) <> vbByte) Then strDelimiter = " " ElseIf VarType(strDelim) = vbByte Then strDelimiter = strDelim ElseIf strDelim > "" Then strDelimiter = Left(strDelim, 1) Else strDelimiter = " " End If strString = Trim(inString) If strString <> "" Then intStartPos = 1 intOrd = 0 Do intPos = InStr(intStartPos, strString, strDelimiter) If intPos > 0 Then arrOrd(intOrd) = Mid(strString, intStartPos, intPos - intStartPos) intStartPos = intPos + 1 Else arrOrd(intOrd) = Mid(strString, intStartPos) End If intOrd = intOrd + 1 If intOrd > UBound(arrOrd) Then ReDim Preserve arrOrd(0 To UBound(arrOrd) + 100) End If Loop Until intPos = 0 intOrd = intOrd - 1 End If ReDim Preserve arrOrd(0 To intOrd) Split = arrOrd End Function
At din ASP kode melder fejl er klart når databasen giver fejl i funktionen Forekomster, fordi den ikke kender funktionen Split, så melder databasen fejlen, at den ikke kender en sådan funktion tilbage til SQL.
Hjemmesiden kommer stadig med samme fejl: Fejltype: Microsoft JET Database Engine (0x80040E14) Der er en ikke-defineret funktion "Forekomster" i udtrykket.
Du refererer helt sikkert til den database, hvor du har oprettet funktionen Forekomster i modulet?
Jeg synes det er mærkeligt, at den ikke kan finde funktionen. ADO sender bare forespørgslen til udførelse i databasen, så det kan ikke være der, fejlen opstår. Fejlmeldingen lyder jo også på Microsoft JET Database Engine, altså Access. Hvis det ellers er den rigtige database du sender forespørgslen til, er jeg på den...
Databasen er jeg 100% sikker på er den rigtige og opretter jeg en ny varer deri er den også tsraks med, begge moduler er deri og med test linien du har sendt mig får jeg det korrekte resultat men siden fejler når den prøver at eksekver SQL stregen?
str = "(Beskriv100 like '%"& searchArr(0) &"%' or Beskriv like '%"& searchArr(0) &"%' or Fabrikat like '%"& searchArr(0) &"%' OR VareNr like '%"& searchArr(0) &"%') " for f=1 to ubound(searchArr) str = str & " or (Beskriv100 like '%"& searchArr(f) &"%' or Beskriv like '%"& searchArr(f) &"%' OR Fabrikat like '%"& searchArr(0) &"%' OR VareNr like '%"& searchArr(f) &"%') " next
strSQL = "SELECT * FROM varer WHERE " & str & " AND LagerAntal > 0;"
Jo, men jeg tror ikke det er SQL strengen der er forkert. Men for at teste det, så prøv at lægge en response.write strSQL ind lige efter at strengen er dannet. Kør dit ASP script. Det skulle gerne resultere i, at SQL-strengen bliver vist i browseren.
Prøv herefter at kopiere SQL strengen ind i en forespørgsel i selve databasen (copy/paste):
1. Marker forespørgsel i databasevinduet. 2. Klik på Ny i den lille menu øverst 3. Vælg designvisning 4. Klik på luk 5. Skift til SQL visning (menuen Vis, vælg SQL-visning) 6. Indsæt nu den streng der blev opbygget i din ASP-kode. 7. Luk og gem 8. Dobbeltklik på forespørgslen for at udføre den.
For at præcisere: Ved punkt 4 er det Tabellisten som viser hvilke tabeller og forespørgsler der kan arbejdes med, der lukkes. Den skal ikke bruges, da SQL indsættes direkte.
Den viser nogle tomme felter, men kun for nogle af posterne i databasen.
Her var søge strengen SELECT Forekomster(Beskriv100, 'viva')+Forekomster(Beskriv, 'viva')+Forekomster(Fabrikat, 'viva')+Forekomster(Varenr, 'viva') AS ForekomsterTotalt, Varenr, Beskriv100, Beskriv, Fabrikat FROM Varer WHERE (Beskriv100 like '%viva%' or Beskriv like '%viva%' OR Fabrikat like '%viva%' OR VareNr like '%viva%') ORDER BY Forekomster(Beskriv100, 'viva')+Forekomster(Beskriv, 'viva')+Forekomster(Fabrikat, 'viva')+Forekomster(Varenr, 'viva') DESC
Jeg havde sigt efter viva og det er der en del varer med men den kan intet finde af det? Men den burde også tage alle andre oplyninger med i søgningen da den vidre bygges men den skal bare ikke søge efetr forekomster i resten af felterne?
Men jeg har svært ved at tyde din meddelelse: "Den viser nogle tomme felter, men kun for nogle af posterne i databasen."
Er det når du kører den direkte som en forespørgsel i databasen? Hvis den ikke finder nogen rækker, som opfylder kriteriet, vil den alligevel vise feltnavnene.
"Jeg havde sigt efter viva og det er der en del varer med men den kan intet finde af det?"
Måske skulle du prøve at erstatte % med * i like strengen. Det er normalt det tegn Access bruger, selv om der vist i online manualen står, at den understøtter begge tegn. Access 2003, som jeg bruger kan godt køre med %, men med en gammel Access 97 ved man aldrig.
"Men den burde også tage alle andre oplyninger med i søgningen da den vidre bygges men den skal bare ikke søge efetr forekomster i resten af felterne?"
Undskyld, men den sætning forstår jeg slet ikke. :-(
"Men den burde også tage alle andre oplyninger med i søgningen da den vidre bygges men den skal bare ikke søge efetr forekomster i resten af felterne?"
Dette har jeg dog fundet ud af, det var fordi i SQL stregen tager vi kun de felter med som der søge i, men da den også skal vise alle felterne for samme varer skal den have * med så sql'en ser sådan ud:
strSQL = "SELECT Forekomster(Beskriv100, '" & Search & "')+Forekomster(Beskriv, '" & Search & "')+Forekomster(Fabrikat, '" & Search & "')+Forekomster(Varenr, '" & Search & "') AS ForekomsterTotalt, Varenr, Beskriv100, Beskriv, Fabrikat, * " strSQL = strSQL & "FROM Varer " strSQL = strSQL & "WHERE " For f = 0 To UBound(SearchArr) If f > 0 Then strSQL = strSQL & "or " End If strSQL = strSQL & "(Beskriv100 like '%" & SearchArr(f) & "%' or Beskriv like '%" & SearchArr(f) & "%' OR Fabrikat like '%" & SearchArr(f) & "%' OR VareNr like '%" & SearchArr(f) & "%') " Next strSQL = strSQL & "ORDER BY Forekomster(Beskriv100, '" & Search & "')+Forekomster(Beskriv, '" & Search & "')+Forekomster(Fabrikat, '" & Search & "')+Forekomster(Varenr, '" & Search & "') DESC"
Som man kan se første linie med strSQL så ender den nu på ...Fabrikat, * " Så får den alle felter med, men stadig ingen resultater, og % tegnet virker fint for som det jeg indledte med er der % tegnet til søgningen og der virker det fint det er bare det når forekomster blandes ind i det at den klager?
Men klager den da stadig (kommer med en fejlmelding), når du udfører den som en forespørgsel direkte i databasen? Jeg forstod på dig, at den viste felterne, men at selektionen bare ikke gav nogen records/rækker.
Jeg har nu prøvet at oprette en tabel, kaldet Varer med de 4 felter du søger på. Heri har jeg indtastet nogle data, hvor 'viva' er indeholdt i et par af dem.
Her hos mig virker det perfekt. Dog var jeg nødt til at ændre LIKE '%viva%' til LIKE '*viva*' for at få det til at fungere.
Men det har du jo prøvet, ikke?
Jeg har dog kun prøvet med en lokal forespørgsel i databasen, men ellers brugt den funktionskode jeg offentliggjorde i 10/09-2007 23:48:10. Forespørgslen indeholder den SQL du offentliggjorde i 21/09-2007 01:11:27.
Men den lokale forespørgsel virker heller ikke hos dig, vel?
Bummer!!! Nu har jeg prøvet at bruge Microsoft Query til at teste adgangen gennem ODBC, og jeg får nøjagtig samme besked som du: Der er en ikke-defineret funktion "Forekomster" i udtrykket.
Selv når jeg prøver at trække på den foruddefinerede forespørgsel, som fungerer perfekt, når jeg udfører den fra selve databasen, giver den straks samme besked. :-((
Det ser ud til at jeg har ledt dig på vildspor, desværre.
Der er åbenbart forskel på Access og Access' databasemotor, Microsoft JET Engine. Via ODBC har man kun adgang til de funktioner, som JET stiller til rådighed. Access er en overbygning på JET.
That's mighty kind of you, good Sir! - som de ville sige i en god gammel cowboy-film. :-)
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.