Detta är hämtat från en sida där man skall kunna registrera sig som ny medlem, som jag håller på att programmera. I din else-sats loopar du igenom ditt recordset och kollar om anvnamn och/eller email är lika med någon av de variabler du har i select satsen. Om någon av variablerna överenstämmer med recordsetet kan du sätta en variable = true/false. Sedan löser du felmeddelandet med en enkel if-sats. (finns ju tre svar, a eller b samt a och b) Jo, jag tänkte på det också. Men det verkade vara lite omständigt. Hade hoppats på att man kunde sätta upp någon form av flagga för vad som inte fanns av de två. Som du ser ovan så har jag ändrat mig ;-) Ex. Låt bli att loopa, det kostar bara för mycket ... Vad avancerat ni ska göra det. Jag kom på ett mycket enkelt sätt att lösa problemet. Eftersom att RecordSet redan är inställt på rätt rad. Där det eventuellt redan skulle finnas överensstämmande poster. Antingen email eller användarnamn, kan man ju använda denna RecordSet. Ditt förslag kan dock släppa igenom en e-mail som redan finns. Jag förstår inte hur man kan släppa igenom en emailadress som redan existerar. Först i SQL-satsen så tar den reda på om det finns någon post som överstämmer med email/användarnamn. ..."Dock är det som du säger att det kommer visas felaktigt om det finns en post där emailadressen existerar och en annan post där användarnamnet existerar. Nu har servern jag ligger på varit nere ett tag så jag har inte kunnat testa koden om den fungerar som tänkt :Är det email eller användarnamn som redan finns?
Finns det något smart sätt som man kan ange om det är email-adressen eller användarnamnet som redan existerar i databasen? Så att man kan peka på vilket fält som behövs ändras vid registrering.
Så här ser min kod ut nu:
'Till databas
Set rs = Server.CreateObject("ADODB.Recordset")
strSQL = "select * from tabell where user = '" & SQLSaker(Request.Form("anvandarnamn")) & "' OR emailad = '" & SQLSaker(Request.Form("email")) & "'"
rs.Open strSQL, Conn, 2, 3
'Kollar om upptaget
if rs.EOF or rs.BOF then
'Ordnar aktiveringskod
aktiveringskod = tmp()
'Lägger till i databasen och skickar till loggin sidan
rs.AddNew
rs("anvandarnamn") = SQLSaker(Server.HTMLEncode(Request.Form("anvandarnamn")))
rs("namn") = SQLSaker(Server.HTMLEncode(Request.Form("fornamn"))) & " " & SQLSaker(Server.HTMLEncode(Request.Form("efternamn")))
rs("losenord") = SQLSaker(Server.HTMLEncode(Request.Form("losenord")))
rs("email") = SQLSaker(Server.HTMLEncode(Request.Form("email")))
rs("narmastestad") = SQLSaker(Server.HTMLEncode(Request.Form("stad")))
rs("aktiveringskod") = aktiveringskod
rs("registreringsdatum") = Date()
rs.update
Response.Redirect("index.asp?mode=klar")
else
'Om användarnamn eller email är upptaget, felmeddelande
Response.Write("Användarnamnet eller e-mailadressen finns redan registrerat.")
end if
----
Klistra in fel till en börjanSv: Är det email eller användarnamn som redan finns?
Sv: Är det email eller användarnamn som redan finns?
Sv: Är det email eller användarnamn som redan finns?
Det går visst att lösa.Sv: Är det email eller användarnamn som redan finns?
<code>
...
Else
strUser = ""
stremailad = ""
Do while not rs.eof
'//Kolla om anvnamn och/eller email finns
If rs("user") = SQLSaker(Request.Form("anvandarnamn")) then
strUser = "True"
If emailad = SQLSaker(Request.Form("email")) Then
stremailad = "True"
Else
'Gör inget
End If
ElseIf emailad = SQLSaker(Request.Form("email")) Then
stremailad = "True"
End If
rs.movenext
Loop
'//Skriva ut felmeddelande
If strUser = "True" AND stremailad = "True" Then
Response.Write("Användarnamnet och e-mailadressen finns redan registrerat.")
ElseIf strUser = "True" Then
Response.Write("Användarnamnet finns redan registrerat.")
ElseIf stremailad = "True" Then
Response.Write("E-mailadressen finns redan registrerad.")
Else
'Gör inget
End If
End If
</code>Sv: Är det email eller användarnamn som redan finns?
är det en SQL Server? isf är det bättre att skriva en proc, är det inte det så skriv din SQL sats så här
SELECT username FROM USERS WHERE USERNAME = ''bla' AND Email = 'bla@blä.bl'
Sen kollar du helt enkelt,
if(rs.RecordCount > 0) then
han finns
else
han finns inte
end ifSv: Är det email eller användarnamn som redan finns?
Jag skriver helt enkelt in detta vid else-satsen:
<code> 'Kontrollerar om det var användarnamnet eller emailadressen som redan fanns i databasen
if rs("anvandarnamn") = SQLSaker(Request.Form("anvandarnamn")) AND rs("email") = SQLSaker(Request.Form("email")) Then
error = "Användarnamnet och Emailadressen du angav existerar redan"
elseif rs("anvandarnamn") = SQLSaker(Request.Form("anvandarnamn")) Then
error = "Användarnamnet du angav existerar redan"
elseif rs("email") = SQLSaker(Request.Form("email")) Then
error = "Emailadressen du angav existerar redan"
end if
'Om användarnamn eller email är upptaget, felmeddelande
Response.Write error
</code>
---
Finito, det fungerar!Sv: Är det email eller användarnamn som redan finns?
- Du ställer din fråga
- Ditt recordset som du får till svar innehåller två rader. (Den första raden innehåller match på användarnamnet och den andra på email adressen)
Den koll du gör kollar först om båda anvnamn och email stämmer. -> False
Din andra koll ser om anvnamn stämmer -> True
Nu har du alltså två poster i din DB med samma email.
Detta förstod jag att du ville förhindra, eller?
Vad det gäller att loopa igenom två (i en utopi kanske 5) poster mha av loop ser jag inte som en för stor "kostnad".
Det man får ta hänsyn till isf:
- Hur många kommer registrera sig samtidigt?
- Hur mkt trafik kommer sajten ha i övrigt?
Nog om detta, det får Henrik avgöra.
Hopppas att du förstod mitt tanke sätt. Hade du bara haft en variabel att ta hänsyn till så hade ditt förslag fungerat utmärkt.Sv: Är det email eller användarnamn som redan finns?
Om det finns en rad där emailadress och/eller användarnamn redan existerar. Kommer den fångas upp i frågenätet. Dock är det som du säger att det kommer visas felaktigt om det finns en post där emailadressen existerar och en annan post där användarnamnet existerar.
<code>
...
if rs.BOF or rs.EOF then
...
else
'Kontrollerar om det var användarnamnet eller emailadressen som redan fanns i databasen
if rs("anvandarnamn") = SQLSaker(Request.Form("anvandarnamn")) AND rs("email") = SQLSaker(Request.Form("email")) Then
error = "Användarnamnet och Emailadressen du angav existerar redan"
elseif rs("anvandarnamn") = SQLSaker(Request.Form("anvandarnamn")) Then
error = "Användarnamnet du angav existerar redan"
elseif rs("email") = SQLSaker(Request.Form("email")) Then
error = "Emailadressen du angav existerar redan"
end if
'Om användarnamn eller email är upptaget, felmeddelande
Response.Write error & rs.RecordCount
</code>
Att göra en loop på bara de berörda fälten vet jag inte hur jag ska göra, RecordCount på något sätt kanske? Jag tror att det kommer bli en väldigt stor databas, om jag når mina mål.
Annars skulle man kunna göra någon kontroll av användarnamn och email utanför SQL-satsen. Fast det såg jag in något inlägg här på Pellesoft att det inte var lika säkert, av någon anledning. Om man då skulle bryta dessa två variabler fria så skulle man samtidigt kunna göra en koll på om vilken av dem som redan finns eller om båda finns i databasen redan.
På så sätt behöver man bara göra en kolla igenom databasen. Dock kör man lite mer kodning mot databasen, fast det kanske inte spelar så stor roll.
Något i stil med:
<code>
'Till databas
Set rs = Server.CreateObject("ADODB.Recordset")
strSQL = "select * from tabell"
rs.Open strSQL, Conn, 2, 3
strUser = ""
stremailad = ""
do while not rs.EOF or rs.BOF
'//Kolla om anvnamn och/eller email finns
if rs("user") = SQLSaker(Request.Form("anvandarnamn")) then
strUser = "True"
if emailad = SQLSaker(Request.Form("email")) Then
stremailad = "True"
else
'Gör inget
end If
elseIf emailad = SQLSaker(Request.Form("email")) Then
stremailad = "True"
end If
rs.movenext
loop
'Kollar om upptaget
if stremailad = "" and strUser = "" then
...
else
'//Skriva ut felmeddelande
if strUser = "True" AND stremailad = "True" then
Response.Write("Användarnamnet och e-mailadressen finns redan registrerat.")
elseIf strUser = "True" then
Response.Write("Användarnamnet finns redan registrerat.")
elseIf stremailad = "True" then
Response.Write("E-mailadressen finns redan registrerad.")
else
'Gör inget
end If
end if
</code>Sv: Är det email eller användarnamn som redan finns?
"...
Kommentar: Bra att du förstod min förklaring.
Lösningen på detta verkar du ju ha hittat själv genom din något modifierade variant av mitt kodförslag ovan. =)
När jag påstod att denna loop inte skulla vara prestandakrävande så resonerade jag så här:
1.) Hur ofta kommer denna koll att göras?
Svar: Inte ofta iom att den endast körs då användaren registrerar sig första gången och inte varje gång han/hon besöker sidan.
2.) Hur många poster kan loopen tänkas behandla? (notera att det är betydelselöst att ens fundera över hur många använddare som finns i db:n, selectfrågan måste ju ändå gå igenom alla)
Svar: En användare försöker registrera sig med anvnamnet: "Anders" och email: "anders.svensson@swipnet.se". Du kollar mot databasen och får träff.
Iom att din db inte tillåter dubbletter kan du maximalt få två träffar vilket i reliteten inte innebär ngt arbete alls att loopa igenom.
Hur kan jag då säga att du maximalt får två träffar? Om någon tidigare registrerat anvnamnet "Anders" kan ingen annan i din db ha det -> en träff.
Om användaren tidigare registrerat sig så finns hans email i din db -> träff 2. (ingen annan kan ju ha ex. "anders.svensson@swipnet.se" -> email = unik)
Detta blev en liten utsvävning det här....Sv: Är det email eller användarnamn som redan finns?
Jag resonerar som dig nu. Lösningen jag kom på kommer bara kräva en genomgång av databasen. Tror inte att den kommer kräva mer prestanda än en vanlig sql-sats som söker reda på användarnamn och email vilka ska vara lika som det som matats in.
Nu hoppas jag att det inte uppstår några säkerhetsmässiga problem i och med att jag flyttat ut kontrollen mot databasen utanför SQL-strängen. Detta skulle ju kanske tillochmed stoppa SQL-injektioner?
Tack så mycket Anders för dina konstruktiva tankar! :) och alla andra som tog sig tid.
/Henrik