Avatar billede dramsgaard Nybegynder
30. juli 2005 - 16:58 Der er 19 kommentarer og
1 løsning

finde hul i talrække

jeg har en stump kode der finder højeste tal fra en talrække fra en tabel i min db og plusser det med 1, og det virker sådanset fint nok.
men hvis nu der et hul i talrækken i db'en f.eks:
1,2,3,4,_,6,7
så vil min nuværende kode blive =8, men jeg kunne godt tænke mig at finde det første hul i talrækken istedet (i dette eksempel 5)
Hvordan kan man gøre dette??

den kode jeg bruger nu ser sådan ud:   
set rs=MyConn.Execute("select MAX(locID) as sidsteID from location where LocTypeID="&locType)
            locID=int(rs("sidsteID"))+1
          rs.close
          set rs=nothing
Avatar billede keysersoze Ekspert
30. juli 2005 - 17:12 #1
nu ved jeg godt at det ikke er det du spørger om så jeg vil gerne undskylde min indblanden på forhånd... men som udgangspunkt er det en rigtig dårlig idé at genbruge id-numre. Id-numre har det bedst med at være fortløbe, uden gentagelser og uden genbrug af forældende tal - og til det er det klart lettest at lave et autonummeringsfelt i databasen.
Avatar billede thesurfer Nybegynder
30. juli 2005 - 17:12 #2
Eksempel:

dim locID
locID = ""

set rs = myconn.exeute("select * from location order by sidsteID")
if rs.bof or rs.eof then
  response.write "Der er ingen poster i databasen!"
else
  do while not rs.eof
  if rs("sidsteID") = "" then
    locID = rs("id")
    exit do
  end if
  rs.movenext
  loop
end if

if locID <> "" then
  ' ny id er fundet, læg 1 til:
  locID = CInt(locID) + 1
else
  ' der blev ikke fundet et nyt id
  response.write "Der blev ikke fundet noget id"
end if


Det kan være, at der er en "SQL"-version.. men det her burde også virke..

/theSurfer
Avatar billede thesurfer Nybegynder
30. juli 2005 - 17:13 #3
keysersoze> Det kommer an på, hvad det er man vil.. Se f.eks. http://www.eksperten.dk/spm/615386

/theSurfer
Avatar billede thesurfer Nybegynder
30. juli 2005 - 17:16 #4
Rettelse (IF-sætning):

dim locID
locID = ""

set rs = myconn.exeute("select * from location order by sidsteID")
if rs.bof or rs.eof then
  response.write "Der er ingen poster i databasen!"
else
  do while not rs.eof

    if rs("sidsteID") <> "" then
        locID = rs("sidsteID")
    else
        exit do
    end if

  rs.movenext
  loop
end if

if locID <> "" then
  ' ny id er fundet, læg 1 til:
  locID = CInt(locID) + 1
else
  ' der blev ikke fundet et nyt id
  response.write "Der blev ikke fundet noget id"
end if

/theSurfer
Avatar billede keysersoze Ekspert
30. juli 2005 - 17:18 #5
nu har jeg ikke læst hele spm igennem - men i sådan et tilfælde ville jeg mene at man skulle redigere oplysninger i stedet for at slette og så oprette en ny eller (og helst) at det bare var de 20 laveste id'er der var testere.
Avatar billede nielle Nybegynder
30. juli 2005 - 17:19 #6
locId = 1

Set rs = MyConn.Execute("SELECT locID FROM location WHERE LocTypeID=" & locType & " ORDER BY locID ASC"

Do While Not rs.EOF
    If rs("locId") = locId Then
        locId = locId + 1
    Else
        Exit Loop
    End If
    rs.MoveNext
Loop
Avatar billede thesurfer Nybegynder
30. juli 2005 - 17:20 #7
Ahh.. han bruger locID, både som variabel og feltnavn.. havde jeg ikke set..

/theSurfer
Avatar billede dramsgaard Nybegynder
30. juli 2005 - 18:08 #8
thesurfer>> hvis jeg bruger dit eksempel bliver tallet stadig lagt til det højeste tal i tabellen, og når jeg når til 10 får alt hvad man tilføjer efter også 10

sådan ser det ud:
locID= Replace(Trim(server.HTMLEncode(Request.Form("locID"))), "'", "''")
      varfejl=false
      if locID<>"" then
          set rs=MyConn.Execute("Select locID, id from location where locTypeID="&locType)
            while not rs.eof
              if (rs("locID")=locID and int(rs("id"))<>int(id)) then varfejl=true
            rs.MoveNext
            wend
              if varfejl=true then fejlID=locID
          rs.close
          set rs=Nothing
      end if
       
      if varfejl=true or LocID="" then
set rs = myconn.execute("select * from location where LocTypeID="&locType&" order by locID")
if rs.bof or rs.eof then
  response.write "Der er ingen poster i databasen!"
else
  do while not rs.eof

    if rs("locID") <> "" then
        locID = rs("locID")
    else
        exit do
    end if

  rs.movenext
  loop
end if

if locID <> "" then
  ' ny id er fundet, læg 1 til:
  locID = CInt(locID) + 1
else
  ' der blev ikke fundet et nyt id
  response.write "Der blev ikke fundet noget id"
end if

      end if
Avatar billede dramsgaard Nybegynder
30. juli 2005 - 18:26 #9
tanken er at hvis variablen locID er tom skal den finde det lavest mulige nr i tabellen LocID og ligge i variablen LocID, som så vil blive tilføjet med en sql senere.

hvis der er et tal i variablen locID skal den tjekke om tallet findes i forvejen i tabellen locID, hvis det findes returneres fejl, hvis det ikke findes går den igennem og bliver tilføjet med en sql senere
Avatar billede dramsgaard Nybegynder
30. juli 2005 - 18:28 #10
rettelse: Det er kolonnen der hedder "LocID" i tabellen "Location"
Avatar billede nielle Nybegynder
30. juli 2005 - 18:29 #11
Har du kigget på min kode endnu?
Avatar billede polle007 Nybegynder
30. juli 2005 - 18:35 #12
Er løsningen også holdbar, hvis der sidder flere samtidige brugere?
Avatar billede dramsgaard Nybegynder
30. juli 2005 - 18:46 #13
nielle >> får fejl ved exit loop, så har rettet det til exit do...men den tilføjer ikke noget tal
Avatar billede nielle Nybegynder
30. juli 2005 - 19:38 #14
Hvad mener du med "den tilføjer ikke noget tal". Hvor skulle den tilføje noget henne?

Min kode giver dig hullet, såm du bagefter kan aflæse i variablen locId - eller hvis der ikke var noget hul, så værdien maks+1.
Avatar billede dramsgaard Nybegynder
30. juli 2005 - 20:03 #15
nielle>> jeg tilføjer variablen med "hullet" i en sql senere, men kunne ik lige få det til at virke da jeg prøvede...må lige se på det i morgen
Avatar billede nielle Nybegynder
30. juli 2005 - 20:11 #16
Så må du jo heller vise os den kode du bruger der, for så er der noget fisket ved den.
Avatar billede dramsgaard Nybegynder
31. juli 2005 - 21:47 #17
nielle>> jeg kan ikke få det til at virke.
Hvis brugeren ikke indtaster noget, så vil variablen locID være tom, også skal den selv finde det mindst mulige tal i kolonnen locID uden at der kommer dubletter, og give dette tal til variablen LocID.

så vidt jeg kan se er det ikke det din kode gør??
håber det er til at forstå
Avatar billede nielle Nybegynder
31. juli 2005 - 22:05 #18
Trin 1) I mit kode-eksempel startes der med tallet 1 - det er m.a.o. start-kandidaten til et hul.

Trin 2) Derefter trækkes alle locid'erne ud af tabellen i stigende rækkefølge

Trin 3) For hvert af dem der er i tabellen "location" tjekkes det om, det er lig med kandidat-hullet.

Trin 4a) Hvis det er, ja så var "hullet" allerede i tabellen, og så var det altså alligevel ikke noget hul. I disse tilfælde tælles kandidat-hullet 1 op.

Trin 4b) Hvis et derimod ikke er, ja så var kandidat-hullet altås det hul vi ledte efter. I dette tilfælde springer bi ud af løkken.


locId = 1  ' Trin 1)

Set rs = MyConn.Execute("SELECT locID FROM location WHERE LocTypeID=" & locType & " ORDER BY locID ASC"  ' Trin 2)

Do While Not rs.EOF
    If rs("locId") = locId Then  ' Trin 3)
        locId = locId + 1  ' Trin 4a)
    Else
        Exit Do  ' Trin 4b)
    End If
    rs.MoveNext
Loop

Response.Write "Det første frie locId er : " & locId
Avatar billede dramsgaard Nybegynder
01. august 2005 - 13:31 #19
nielle>> smid et svar...jeg har fået det til at virke

problemet var at jeg af en eller anden grund ikke havde fået sat locID kolonnen i databasen til tal
Avatar billede nielle Nybegynder
01. august 2005 - 18:48 #20
Ja, den slags fejl kan jo drille længe før at man opdager den :^|

... og et svar :^)
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