/MYSQL Nach Vorhandensein eines Datensatzes überprüfen?
Markus Trusk
- perl
Hallo,
Ich will bei einer Registrierung überprüfen, ob ein Nickname schon existiert. Dabei verwende ich zum Testen folgenden Code:
my $name = 'markus';
my $dbh = DBI->connect("DBI:mysql:$database:$dbserver", $user, $pass, {AutoCommit => 0}) or die "Cant connect : $!\n";
my $auslesen = $dbh->prepare("SELECT * FROM users WHERE nick='$name'") or die "$!\n";
$auslesen->execute;
print "Content-type:text/html\n\n";
while (my($nick,$pass,$email,$firstname,$propername,$homepage,$icq,$gebdate,$location) = $auslesen->fetchrow_array) {
print "$nick, $pass, $email, $firstname, $propername, $homepage, $icq, $gebdate, $location <br>";
}
$auslesen->finish;
$dbh->disconnect;
Jetzt könnte ich natürlich überprüfen, ob die Ausgabe leer ist oder nicht, und je nachdem schlussfolgern, ob der Name eben existiert oder nicht, aber das Ganze erscheint mir relativ umständlich. Wie könnte ich die Suche effizienter gestalten?
Markus Trusk.
Hallo,
Ich will bei einer Registrierung überprüfen, ob ein Nickname schon existiert. Dabei verwende ich zum Testen folgenden Code:
Wie könnte ich die Suche effizienter gestalten?
Das kommt darauf an. Willst Du wirklich nur wissen, ob der Nickname schon existiert, dann reicht ein "SELECT COUNT(*) FROM USERS WHERE NICK = 'Wasauchimmer'". Wenn das Ergbins 0 ist, dann gibt's den Nickname noch nicht, andernfalls schon (wobei Du eventuell noch auf eine beliebige Gross-Klein-Schreibung-Regelung Rücksicht nehmen willst). Bei vernünftiger Datenbankkonfiguration ist das auhc dann noch effizient, wenn schon viele Daten in der Tabelle stehen (Stichwort Index).
Wenn Du aber mit dem (eventuell) gefundenen Datensatz noch mehr anstellen willst, dann ist Deine Lösung schon recht gut.
In beiden Fällen würde ich mir noch Parameter-Binding 'antun', da damit viele allfällige Probleme umgangen werden (Was ist, wenn der Nick ein Anführungszeichen beinhalten soll?).
Grüße
Klaus
Hallo,
danke für den Tipp. Ich habe es jetzt so entgültig gelöst:
my $dbh = DBI->connect("DBI:mysql:$database:$dbserver", $dbuser, $dbpass, {AutoCommit => 0}) or die $DBI::errstr;
my $auslesen = $dbh->prepare("SELECT COUNT(nick) FROM users WHERE nick='$nick'") or die $dbh->errstr;
$auslesen->execute;
my $readnick = $auslesen->fetchrow_array;
$auslesen->finish;
$dbh->disconnect;
if ($readnick != 0) {
return 'This nickname already exists. Please choose another one !';
}
In beiden Fällen würde ich mir noch Parameter-Binding 'antun', da damit viele allfällige Probleme umgangen werden (Was ist, wenn der Nick ein Anführungszeichen beinhalten soll?).
Also das mit der Parameterbindung verstehe ich nicht so ganz, aber das Problem mit den Entities habe ich bereits so gelöst, dass ich die Variablen, die Sonderzeichen enthalten könnten, mit HTML::Entitites kodiert, sodass diese gleich als kodiert in die Datenbank eingelesen werden.
(Zumindest hat sich diese Methode bei meinen früheren Daten Ein,-Auselese Scripts bewährt, und jetzt bei mySQL sollte es sicher auch funktionieren)
Markus Trusk.
use Mosche;
Also das mit der Parameterbindung verstehe ich nicht so ganz, aber das Problem mit den Entities habe ich bereits so gelöst, dass ich die Variablen, die Sonderzeichen enthalten könnten, mit HTML::Entitites kodiert, sodass diese gleich als kodiert in die Datenbank eingelesen werden.
(Zumindest hat sich diese Methode bei meinen früheren Daten Ein,-Auselese Scripts bewährt, und jetzt bei mySQL sollte es sicher auch funktionieren)
$nick = 'blah'; delete from users where nick != 'bjkh';
hat dein Script ganz schnell raus gehauen, weil dann nämlich das delete noch ausgeführt wird. Besser:
$sth = $dbh->prepare("select from users where nick = ?");
$sth->execute($nick);
oder:
$nick = $dbh->quote($nick);
$sth = $dbh->prepare("select from users where nick = $nick"); # jetzt ohne anführungsstrichelchen
$sth->execute();
Die erste Methode ist vorzuziehen, weil du dann das Statement-Handle noch weiterbenutzen kannst (wenn du zB noch einen anderen Usernamen abfragen willst, reicht es, nochmals $sth->execute('neuer_nick') aufzurufen).
use Tschoe qw(Matti);
Hi,
danke für den Tipp. Ich glaube, da hätte ich noch ein paar böse Überraschugnen erlebt :) Gibt es noch mehrere solcher Schlupflöcher, auf die ich aufpassen sollte?
Markus Trusk.