27. februar 2014 - 17:09Der er
9 kommentarer og 1 løsning
Find et bestemt tal i en talmængde
Jeg har nu i et par dage bokset med et problem uden at finde en løsning, så jeg håber på hjælp her.
Jeg har en meget langt SQL-Query (i mit klassiske asp-program), som skal hente data fra min access database. Der søges på omkring 30 felter i databasen, og det går ok for de 29 felter. Søgekriterierne for det 30. felt giver derimod problemer. Jeg får ikke en fejlmeddelelse, men jeg kan se, at søgningen opgiver at finde det, den skal.
Det famøse felt i Access er et tekstfelt, der hedder "madtil" og det kan have værdierne Null eller ét tal eller en række tal separeret med kommaer. Fx record1=17 record2=2,12,1 record 3=null record4=33,21,924 osv.
Min opgave er nu at hente de records, som indeholder et bestemt tal, som jeg har gemt i tekstvariablen "lmad", fx tallet 1.
Jeg kan ikke blot bruge funktionen InStr(madtil,lmad) direkte, for den vil fejlagtigt udpege record1, record2 og record4 i stedet for alene record2.
Jeg håber nogle før mig har en løsning, som kan puttes ind i min sql-query. Altså et logisk udtryk med variablerne madtil og lmad.
Det ser spændende ud. Jeg er dog ikke en ørn til vbscripting så lige 2 spørgsmål. 1) sikrer de firkantede parenteser at der ledes efter databasefeltet inden i parenterne? Altså at der ledes efter feltet madtil og ikke efter et ikke-eksisterende felt med navn ,madtil, ?
2) min søgestreng skal nu hedde strSQL = strSQL & " AND ........" - hvor prikkerne skal erstattes af dit forslag , ikk?
Men strSQL = strSQL & " AND ',' & [madtil] & "',' like '*,'" & lmad & "," er åbenbart ikke korrekt.
Har også uden held forsøgt med strSQL = strSQL " And Instr(','[madtil]','," & lmad & ")"
Brug af feltnavne i kantparenteser er noget jeg kender fra ms-access som office produkt - de behøver sådan set ikke altid at være der - men jeg brugte det som en slags signatur for at fastslå at der var tale om feltnavn.
Jeg aner faktisk ikke om man bruger det i asp
Lidt kryptiske sql udtryk sammensætninger kan godt drille - det er nyttigt at testudskrive strengen. Måske løser det det:
strSQL=strSQL & " AND ',' & madtil & ',' like '*," & Imad & ",*'"
Jeg føler, at jeg er godt på vej - men er ikke i mål endnu.
Sætningen med " AND ','madtil',' like '*," & lmad & ",*'" bliver testudskrevet som AND ','madtil',' like '*,1,*' men den fanger IKKE den record i db som indeholder værdien 1
Har også forsøgt med " AND ',[madtil],' like '*," & lmad & ",*'" der udskrives som AND ',[madtil],' like '*,1,*' men igen uden at fange den record(nr. 26) der indeholder 1
Kalder i det følgende det følgende den databaseproces der modtager sql strengen for JET
Læg mærke til at der på en måde er 2 slags '&' tegn i udtrykket.
1. '&' som vi videregiver til JET - JET kender til feltet 'madtil' og kan dermed evaluere udtryk som ',' & madtil & ',' Hvis en feltværdi er '1,4,77' sammensættes JET de 3 strenge; ',', '1,4,77' og ',' til strengen ',1,4,77,' (bemærk: indledene og afsluttende komma tegn)
2. '&' tegn hvormed strenge sammensættes - en operator hvormed udtrykket med to delstrenge "hello " & "world" bliver til "hello world"
Det en testudskrift skal vise er, givet Imad=1:
AND ',' & madtil & ',' like '*,1,*'
Så vidt jeg kan se får du ikke '&' med til som del af strSQL
Hvis vi nu simplificerer problemet, og blot beder om at udpege alle record, som i feltet madtil har præcis tallet 1 alene uden andre (altså hvor madtil = lmad)- så virker det, når jeg skriver
" AND madtil like " & lmad
Hvis jeg så fortsat vil lave denne udpegning, men tilføje nogle uskadelige wildcards, prøver jeg med
" AND '*' & madtil & '*' like " & lmad, så udpeges der INTET og sql-udskriften er AND '*' & madtil & '*' like 1 Jeg får intet udpeget og den udskrevne sql-sætning ser også forkert ud. Jeg havde forventet *madtil* og ikke '*' & madtil & '*'
Du gør ikke noget forkert - forsøger forskellige ting jeg ikke forstår hensigten med, og er ikke helt tilfreds med resultatet ;)
Hvorfor anvender du i #6 '*' tegn på venstre side af like ? Prøv at orientere dig om hvordan like virker - du har ingen stjerner i dit feltindhold - citeret fra #1 'Fx record1=17 record2=2,12,1 record 3=null record4=33,21,924 osv.'
Et mere anvendeligt resultat, kan opnåes vha. et udtryk der giver den testudskrift jeg angiver i #5 - et bud på udtrykket er sidst i #3
Mit forrige forsøg gik på at tjekke om jeg brugte wildcard korrekt. Altså at tilføje et wildcard til en streng der virker - og derfor også burde virke efter tilføjelsen af wildcard. I w3school skriver de faktisk, at man skal bruge % og ikke *, når man bruger LIKE (http://www.w3schools.com/sql/sql_wildcards.asp).
Men heller ikke dette virkede.
Jeg er nu krøbet til korset og har ændret indsættelse i databasen, sådan at indholdet af feltet madtil altid starter og ender med et komma - altså record1=,17, record2=,2,12,1, record3=null record4=,33,21,924, osv.
Så nu kan jeg få det til at virke, når lmad ændres til lmad = "," & lmad & "," og min søgestreng hedder
Instr(madtil,lmad) > 0
Er dog lidt ked af at det ikke lykkedes at få LIKE med kommaer og wildcards til at virke.
Indholdet i madtil er konceptionelt en postliste pakket ind i en enkelt post. Det bryder gængse relationsdatabase struktureringprincipper at indkapsle felter eller poster i et enkelt felt. Sådan ville jeg gøre: Tabellen T med 29 felter har 4 poster med id=1 til id=4 Tabellen Madtil (t_id,madNr) har posterne: 1,17 2,2 2,12 2,1 4,33 4,21 4,924
Find de poster I T som relaterer til Madnr=12:
select * from T inner join Madtil on T.id=Madtil.t_id where madNr=12
Iøvrigt er sql et sprog med mange dialekter - det er udmærket at orientere sig generelt på w3c's lette tutorials, men den præcise syntaks skal findes hos producenten bag en given sql implementation - aktuelt anvender microsoft * hvor andre anvender % i like.
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.