Inhalt in der Datenbank prüfen?

Simi

Angesehenes Mitglied
Hi all,

Eine Frage...habe irgendwie wieder Mal einen Blackout.
rolleyes.gif


Ich möchte einen Datenbankeintrag über einen Formular machen. Jedoch
soll vorher gecheckt werden ob diesen Eintrag bereits in der Datenbank existiert.
Die Rede ist hier nur von einer Zelle die kontrolliert werden muss.

Kann mir jemand sagen bzw. schreiben wie ich die if Abfrage am besten stelle? Im Prinzip sollte es
so sein wie wenn sich ein User registiert...dort wird ja au gecheckt ob er bereits existiert.

Vielen Dank im Voraus.

Gruss
Simone
 
Sollte doch so kein Problem sein:
CODE $abfrage= ("SELECT id FROM `blubb` WHERE eintrag='".$eintrag."'");
$result = mysql_query($abfrage,$conn);
$row = mysql_fetch_array ($result);
$id = $row['id'];
if(isset($id) OR $id != ""){
echo "gibts schon...";
}else{
$abfrage = ("INSERT INTO `blubb` ( `eintrag` ) VALUES ('".$eintrag."')");
$result = mysql_query($abfrage);
};
 
Kannst auch mit der Funktion mysql_num_rows() arbeiten. Würde dann etwas so aussehen:

CODE
$abfrage= "SELECT * FROM `blubb` WHERE eintrag='".$eintrag."'";
$result = mysql_query($abfrage,$conn);
if(mysql_num_rows($result) == "0"){
  echo "Gibts nicht";
}else{
  echo "Leider schon vergeben";
}

 
Beide Lösungen sind falsch, da die beiden Befehle Abfrage und Einfügen keine atomare Einheit bilden, also sich jemand anderes mit demselben Namen dazwischen anmelden kann.

Entweder das ganze in einer gespeicherten Prozedur als Transaktion kapseln, die Transaktion vom Client her initiieren oder eine Unique-Einschränkung setzen und den Fehler abfangen.
 
@jAuer
was meinst Du genau damit?
ist das "nur" eine Anspielung auf SQL injections? oder hat das noch andere hintergründe ???

würde es nicht ausreichen wenn man bei diesne beiden Codes für dem Ausführen der Abfrage die Variable $eintrag absichert?
also auf unerwünschte Zeichen prüft ???

wenn Du das nicht meinst, vielleicht kannst Du ja mal einen Code Posten, ??

denn offen gesagt würde ich es genauso machen
 
Das hat nichts mit Sql-Injektionen zu tun.

Es kann der Fall auftreten, daß zwei verschiedene Nutzer gleichzeitig versuchen, sich mit demselben Namen anzumelden. Und dann ist es möglich, daß die beiden Abfrageergebnisse, die sagen, daß es diesen Namen noch nicht gibt, praktisch zeitgleich zurückgegeben werden. Also 'denken' beide Scripte, daß sie das Insert ausführen können. Das erste Script trägt den Namen ein - und das zweite Script versucht entweder dasselbe (dann gibt es den Namen doppelt) oder crasht (hoffentlich) über die Unique-Einschränkung.

QUOTE vielleicht kannst Du ja mal einen Code Posten, ??


Ich verwende kein PHP und weiß deshalb nicht, ob PHP Transaktionen unterstützt.

In NET + MS-SqlServer würde man einen einzigen langen Befehl draus machen:


CODE Begin Transaction
If (Exists (Select id From Nutzer Where Nutzername = Variablenwert))
Insert Into Nutzer(Nutzername) Values (Variablenwert)
If (@@RowCount = 1) Commit Transaction Else Rollback Transaction


Auf richtigen Systemen macht man aus dem obigen eine gespeicherte Prozedur, ruft diese auf und verzweigt dann in Abhängigkeit vom Statuswert.

 
ach so war das gemeint.
Danke für die erklärung.
aber ob es dafür in PHP eine lösung gibt wüste ich jetzt nicht(aber vielleicht jemand anderes hier??)

im Grunde wäre das vielleicht sowas ähnliche ein flock bei bei textdateien?
dadurch wird dann die Datei für andere zugriffe gesperrt und erst nach der "eigenen" Aktion
wieder freigegeben.

aber ob es das auch in php für den Datenbankzugriff gibt ???

andersrum werden jetzt sicher viele sagen, das die Wahrscheinlichkeit, das sowas passiert äußerst gering ist.
aber trotzdem sollte sowas sowas nicht komplett ausgeschlossen werden.

also wer dazu vielleicht ideen oder Tips hat,
immer her damit
ich bin äußerst Wissbegierig...
 
Evt wäre die Möglichkeit, nach dem Eintrag zu überprüfen ob wirklich nur 1 Eintrag vorhanden ist, falls nein, dann wird der letzte Eintrag (man hat ja noch alle Daten) einfach wieder gelöscht und der Fehler ausgegeben. Somit würde sich der "schnellere" eintragen, denn dann gibt es nur einen Eintrag und beim 2. würde dann der Fehler kommen und wichtig ist, die Daten wieder aus der DB zu löschen, da sie ja schon in die DB geschrieben wurden.
 
QUOTE (Metaman @ Do 20.4.2006, 22:56)[...] aber ob es dafür in PHP eine lösung gibt wüste ich jetzt nicht(aber vielleicht jemand anderes hier??) [...]

Natürlich kann PHP mit Transaktionen umgehen, vorausgesetzt die Datenbank bzw. der Tabellentyp unterstützt dies.
Bei MySQL muss als Tabellentyp "InnoDB" statt dem Standardtyp "MyISAM" ausgewählt werden. Kleiner Tipp dabei Abfragen wie diese (siehe SQL-Code) mag MySQL dann aber nicht und gehen massiv auf die Preformence.

SQL SELECT COUNT(*) FROM tabelle WHERE wert > 10;


Auch funktioniert ein Volltext-Index nicht mehr.


Es reicht aber im Prinzip auch ein entsprechender UNIQUE Key, wobei die Fehlermeldung jedoch besser von dem PHP-Script abgefangen werden sollte, Transaktionen muss man dazu nicht unbedingt verwenden. Nur eine einfache vorherige Abfrage, ob der entsprechende Benutzer nicht innerhalb der Tabelle vorhanden ist, reicht definitiv nicht aus. Natürlich muss hierfür die Datenbankstruktur richtig entworfen werden.

Bei Systemen, welche mit Geld, insbesondere mit Geldtransaktionen, zu tun haben (wie z. B. ein Online-Shop), sollte jedoch unbedingt mit Transaktionen gearbeitet werden.

<edit>
Die UNIQUE-Key Variante funktioniert natürlich nur, wenn auch nur eine Tabelle bearbeitet wird, bei mehreren Tabellen sollte man dann doch besser auch auf Transaktionen umsteigen.
</edit>



MfG Sascha Ahlers
 
QUOTE (jAuer @ Do 20.4.2006, 22:38)
CODE Begin Transaction
If (Exists (Select id From Nutzer Where Nutzername = Variablenwert))
Insert Into Nutzer(Nutzername) Values (Variablenwert)
If (@@RowCount = 1) Commit Transaction Else Rollback Transaction



Nicht ganz einverstanden ;-)

Die Transaction verhindert nicht, dass weitere Records in der Tabelle eingefügt werden. Wenn schon, müsste man nach dem Einfügen prüfen ob mehr als ein Record mit dem gleichen Nutzernamen existiert. Das lässt sich aber durch eine Unique-Einschränkung auf dem Nutzernamen einfacher verhindern, damit wird die Transaction dann überflüssig.

Griessli
Irene
 
Hm... Da müsste man ja gleich die ganze Tabelle sperren, damit niemand dazwischen funkt...?
 
QUOTE (Irene @ Fr 21.4.2006, 8:12)
QUOTE (jAuer @ Do 20.4.2006, 22:38)
CODE Begin Transaction
If (Exists (Select id From Nutzer Where Nutzername = Variablenwert))
Insert Into Nutzer(Nutzername) Values (Variablenwert)
If (@@RowCount = 1) Commit Transaction Else Rollback Transaction



Nicht ganz einverstanden ;-)

Der Code funktioniert auf dem MS-SqlServer, sofern die Transaktionsisolationsstufe korrekt auf SERIALIZABLE gesetzt ist. Praktisch verwende ich in solchen Fällen UNIQUE (siehe #4) plus Abfangen des Fehlers auf dem Client.
 
Hi Roberto,

Da ich noch ein Anfänger bin habe ich deine Variante versucht!

Und zwar folgendermassen:

CODE


$abfrage= "SELECT * FROM `blubb` WHERE eintrag='".$eintrag."'";
$result = mysql_query($abfrage,$conn);
if(mysql_num_rows($result) == "0"){
echo "Gibts nicht";
}else{
echo "Leider schon vergeben";
}




Bei mir hat das leider nicht funktioniert...der Eintrag wird trotzdem eingetragen.

Hast du mir noch ein Vorschlag?

Gruss
Simi
 
Hallo Simi

Kannst du vielleicht mal deinen Code Abschnitt posten, denn bei mir funktioniert das.
Evt. auch mal die Fehler die evt. entstehen mit

CODE
echo mysql_error();



ausgeben.
 
@Simi
dieser Code funktioniert schon
wenn Du den Code natürlich so übernimmst, wie hier gepostet dann kann es nicht 100 % laufen.
also wenn Du deinen Code der die Daten einträgt, einfach nach diesem Codestück schreibst,
wird das Script die Meldung ausgeben, und dann ganz normal weitermachen.

Wenn Du aber deinen Code zum Eintragen der Daten in der schleife einsetzt, also an stelle des
echo "Gibts nicht";

dann werden die Daten auch nur dort gepeichert, wenn die SQL Abfrage 0 ergibt.
allerdings würde ich das etwas umändern.

CODE $abfrage= "SELECT * FROM `blubb` WHERE eintrag='".$eintrag."'";
$result = mysql_query($abfrage,$conn);
if(mysql_num_rows($result) >= 1){
echo "Leider schon vergeben";
}else{
### HIER DEIN CODE zum Eintragen der Daten
}
 
Hallo zusammen,

Danke für die super schnelle Antwort...ist ja unglaublich.
ph34r.gif


Es war alles richtig eingestellt nur die Abfragungen verkehrt.
rolleyes.gif


Danke noch mal und nice Weekend wünsch ich noch!

Gruss
Simi
 
Hi,

So geht's auch und mit unbuffered_query blockst du gleichzeitig den table:

$rs=mysql_unbuffered_query($sql,$link)or $conny=true;
if(!$conny){
if($rf=mysql_fetch_row($rs))print 'schon da';
else print 'insert';}
else print 'kleiner technischer Fehler';

Gruss

Bernd R. Rickert
 
Zurück
Oben