Avatar billede Slettet bruger
09. juni 2007 - 22:49 Der er 17 kommentarer og
1 løsning

en jeg ikke lige kan greje

Hejsa

Jeg har her en kode som skal lave en registreringsnøgle til en ny bruger i et oprettelsessystem:

randomize
pwdlen=10
pwd=""
pwdchr="abcdefghjkmpqrstuvwxyz123456789"
chrlen=len(pwdchr)
for n=1 to pwdlen
x=Int((chrlen-1+1)*Rnd+1)
pwd=pwd & mid(pwdchr,x,1)
next

Denne kode skal gemmes i en access-database ved oprettelse. Det jeg så ikke lige kan gennemskue er hvordan jeg kan sørge for at registreringsnøglen er unik sådan at den ikke findes andre steder i tabellen i databasen - og hvis den gør skal der genereres en ny registreringsnøgle.

jeg regner med noget med at vi skal lave et select-opslag som følgende:

set rs = conn.execute("select * from users where regk='" & pwd & "'")
if rs.EOF=True then

else

end if


- men hvordan fletter vi det sammen sådan at registreringsnøglen ALTID vil være unik?

\Dan
Avatar billede nielle Nybegynder
09. juni 2007 - 23:02 #1
Noget i denne stil?

Randomize
pwdlen = 10
pwdchr = "abcdefghjkmpqrstuvwxyz123456789"
chrlen = len(pwdchr)

Do
    pwd = ""
    For n = 1 to pwdlen
        x = Int((chrlen-1+1) * Rnd + 1)
        pwd = pwd & mid(pwdchr,x,1)
    Next

    sql = "SELECT count(*) AS antal FROM users WHERE regk = '" & pwd & "'"
    Set rs = conn.Execute(sql)
    antal = rs("antal")
While antal <> 0

sql = "INSERT INTO users (regk) VALUES ('" & pwd & "')"
conn.Execute(sql)
Avatar billede nielle Nybegynder
09. juni 2007 - 23:14 #2
Iøvrigt må:

x = Int((chrlen-1+1) * Rnd + 1)

- da kunne forenkles til:

x = Int(chrlen * Rnd + 1)
Avatar billede softspot Forsker
10. juni 2007 - 00:46 #3
...og så bør du nok lave en transaktion omkring hele molevitten, da du ellers (teoretisk set) kan risikere, at en anden opretter en række med nøglen efter løkken, der finder ud af om nøglen er entydig, er afsluttet og selve indsættelsen gennemføres.

Alternativt kan du sætte feltet til entydigt i databasen, og så bare indsætte nøglen uden at checke i forvejen - og så bare reagere på den fejl som indsættelsen vil resultere i, hvis nøglen findes i forvejen. Jeg tror faktisk denne løsning, overordnet set, vil performe bedre end at checke i forvejen, da nøglen i langt de fleste tilfælde, vil være entydig. At databasen er så fyldt at du får sammenfald ofte er vist mest en teoretisk overvejelse...

Hvilken løsning du vælger er vist mere et spørgsmål om religion (hvad man synes er mest rigtigt) end noget andet, da jeg som sagt ikke ser nøglesammenfald som en hyppigt forekommende begivenhed :)
Avatar billede Slettet bruger
10. juni 2007 - 15:42 #4
hej nielle

- mange tak for dette bud... Jeg skal nok lige få set på det - men jeg var lige løbet ind i nogle andre problemer med det websted jeg sidder og laver, og derfor fik jeg ikke lige svaret tilbage igen promte...

\Dan
Avatar billede Slettet bruger
10. juni 2007 - 15:43 #5
>> Softspot - Det er således lavet at denne registreringsnøgle SKAL være unik eller vil resten fejle... Så derfor vil jeg ikke tage nogle chancer hvad dette angår..

\Dan
Avatar billede nielle Nybegynder
10. juni 2007 - 16:00 #6
Nu skal vi vist heller ikke overdrive risikoen.

Fejlen kan kun opstå hvis der er to forskellige brugere som forsøger at tilmelde sig på *samme* tid og at de tilfældigvis generere det samme regk. Odds for at dette sker er i øvrigt:

1 : 31^10 - altså - 1 : 819.628.286.980.801

I praksis vil dette kun ske på et meget befærdet site... Med et sammenfald i sekundet vil der stadig i gennemsnittet gå omkring 25 mill. år før det går galt. :^)

Men hvis du gerne 100% vil garaentere unikhed, hvorfor så ikke bruge et auto_increment felt?

Eller, som det aller mindset kan du ihvertfald erklære din dit regk felt til at være unikt. Så kan du reagere på det meget-meget-meget sjældne tilfælde hvor koden skulle komme til at lave den samme kode.
Avatar billede Slettet bruger
10. juni 2007 - 16:17 #7
Hej nielle

Nej det handler ikke om hvor mange brugere der er der på samme tid...

regk som skal genereres må jo ikke findes i tabellen i databasen i forvejen... i kollonnen "regk"!

Så hvis vi for eksempel har en milliard registrerede brugere så kunne problemet jo sagtens opstå - endda med ret stor sandsynlighed...    ;-)

- Men hvorfor ikke bare være på den sikre side? Som for eksempel med den kode du gav mig...

\Dan
Avatar billede nielle Nybegynder
10. juni 2007 - 17:56 #8
> regk som skal genereres må jo ikke findes i tabellen i databasen i forvejen... i kollonnen "regk"!

Min kode indeholder jo et tjek af om det findes i forvejen. Det er kun hvis to brugere er på på samme tid og får genereret den samme kode at det kan gp galty.
Avatar billede Slettet bruger
10. juni 2007 - 21:30 #9
Ja enig - nielle!

- men hvis ikke man laver dette tjek om regk er unik så vil det hele fejle senere hen også... og det er det jeg gerne vil undgå med 100% sikkerhed...

- så mange tak for dit script - og smid et svar for point...

\Dan
Avatar billede nielle Nybegynder
10. juni 2007 - 21:42 #10
Svar :^)
Avatar billede Slettet bruger
10. juni 2007 - 22:07 #11
- og tak for hjælpen!

\Dan
Avatar billede softspot Forsker
11. juni 2007 - 08:33 #12
Ehm, jeg kan ikke helt forstå hvad der var galt med det jeg sagde - jeg synes jo bare nielle bekræftede det - netop at sandsynligheden for sammenfald er lille og at du under alle omstændigheder kunne sætte kolonnen til unik, for så ville databasen melde en fejl hvis du forsøgte at indsætte en værdi som eksisterede i forvejen - og du kunne generere en ny og forsøge indsættelse igen...

Jeg er ikke ude på at få omstødt din pointtildeling, bare at få anerkendt, at jeg ikke bare fyrede noget ævl af :D
Avatar billede softspot Forsker
11. juni 2007 - 08:36 #13
Et andet alternativ var at benytte en GUID som nøgle, for den er unik uanset hvad der sker :)
Avatar billede melieha Nybegynder
11. juni 2007 - 11:59 #14
Hvis ikke der er krav til en specifik længde af nøglen, så er det vel bare at indsætte dato og tid (Til og med ms?) først, sidst eller et sted i nøglen.
Avatar billede nielle Nybegynder
11. juni 2007 - 19:42 #15
softspot> Du har bestemt ikke sagt noget vrøvl. Det virkede bare som om at dannielsen med 10/06-2007 15:43:45 var ved at ville indføre transaktion *oven i* min løsning for at blive 101 % sikker ... og det synes jeg lige skulle sættes lidt i perspektiv. Nu hvor at jeg læser det hele igen, kan jeg se at det måske ikke lige var det der var ment, og for det undskylder jeg. :^)
Avatar billede softspot Forsker
11. juni 2007 - 22:09 #16
nielle >> Godt så! :D

Jeg reagerede nu også mest på Dan's indlæg 10/06-2007 15:43:45, idet jeg gerne ville have haft ham til at sætte en transaktion omkring det du foreslår - specielt set i lyset af det ultimative krav om entydighed, da der (indrømmet MEGET) teoretisk set, kan komme en ind imellem denne linie i while-løkken udføres:

    Set rs = conn.Execute(sql)

og disse linier efter while-løkken udføres:

sql = "INSERT INTO users (regk) VALUES ('" & pwd & "')"
conn.Execute(sql)

og indsætte en nøgle som gør at indsættelsen resulterer i en dublet.

Mit andet løsningsforslag var at sætte regk til at være entydig (ligesom du også foreslår) og så reagere på den fejl databasen vil kaste, hvis der er sammenfald mellem den nøgle man forsøger at indsætte og en der eksisterer i forvejen. Mit argument for at vælge denne løsning, var, som du ligeledes lavede noget imponerende talgymnastik over, dels at sammenfald vil ske så sjældent at det praktisk talt ville være aldrig, dels at entydigheden forventelig håndhæves af databasen i en tabellåsning, hvilket betyder at en transaktion egentlig er overflødig i det scenarie.
Avatar billede Slettet bruger
11. juni 2007 - 22:55 #17
Hej Softspot - og andre

Jeg har på intet tidspunkt ville "træde dig over fødderne"!
Og jeg skal da også indrømme at jeg måske nok overså dit indlæg en anelse i starten... Det er jeg ked af og det må du meget undskylde...

Nu kommer der så lige lidt af baggrunden for hele dette her "kaos", om man vil...
Jeg er ved at lave et system for en forretning som skal have et system som kan oprette nye brugere (blandt andet) og kunderne/brugeren får så et "adgangbevis" udskrevet hvor denne her famøse registreringsnøgle skal være på. Og så når kunden kommer hjem og vil til at bruge systemet så skal de registrere sig ved netop at bruge denne nøgle. Og så har vi jo et alvorligt problem hvis denne nøgle eksisterer i databasen mere end en gang! Det kan være I siger at dette er meget usandsynligt, men på den anden side vil jeg så heller ikke lave noget som har sådant en risiko...

- Egentlig er jeg lidt flov over at jeg ikke selv kan klare denne relativt harmløse opgave - for det burde jeg egentligt kunne når man tænker på hvor meget andet jeg har lavet - men sådan kan der jo være "huller" i ens viden en gang i mellem...

Men tak for hjælpen og inspirationen til alle! Og hvis du gerne vil have point også, softspot, så sig til...

\Dan
Avatar billede softspot Forsker
11. juni 2007 - 23:12 #18
Dan >> Nej, nej, det er var ikke for at få point og det var heller ikke et udtryk for at jeg var fornærmet, det var bare for at være sikker på at du havde forstået risikoen (selvom den er teoretisk) ved det forslag som nielle stiller og de scenarier, jeg stiller op, hvormed det kan løses.

Jeg kan da sagtens følge dig i, at du gerne vil have en 100% skudsikker løsning f.s.v.a. entydighed - og det synes jeg du har fået - omend i en lidt abstrakt form fra min side (men da dit tekniske niveau jo er højere end mange andres herinde, så mente jeg nok du selv kunne finde ud af den konkrete løsning)... :-)
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