Moin!
sehr einfache Aufgabe:
Ich möchte einen datenbank-INSERT davon abhängig machen, ob ein solcher Eintrag bereits vorhanden ist.
Dazu mache ich eine simple SELECT-abfrage nach dem entsprechenden Feld und möchte mit mysql_num_rows abfragen wieviele Ergebnisse diese lieferte.
Das ist die naheliegende Strategie, die aber in gewissen Szenarien, die du nicht ausschließen kannst, scheitern wird.
Stell dir einfach nur mal vor, zwei parallele Skriptaufrufe wollen die gleichen Daten insertieren. Dann kriegt die Skriptinstanz, die "zufällig" das erste SELECT abschickt, grünes Licht: Nix gefunden. Dann kommt die zweite Skriptinstanz und kriegt ebenfalls grünes Licht.
Skriptinstanz Nummer 1 schreibt jetzt das INSERT in die DB. Funktioniert alles, wie du es dir denkst. Und dann kommt Skript Nummer 2 und versucht dasselbe nochmal... BUMM. Wobei die Art und Weise des "Bumm" davon abhängt, was in so einem Doppelbelegungsfall in deiner DB passiert.
Die schlauere Alternative ist, durch einen Index sicherzustellen, dass garantiert keine doppelten Daten in einer Spalte, oder einer Spaltenkombination, eingefügt werden können - und dann einfach strikt INSERT zu benutzen, die DB wird sich mit einem Indexfehler melden, wenn der Datensatz schon vorhanden ist - ganz unabhängig von vorhergehenden SELECTs.
Es gibt auch die Variante, in dem Fall, dass das INSERT wegen Doppelbelegung scheitert, direkt ein UPDATE zu machen. Auf diese Weise implementiert man sehr einfach Aktualisierungen von bestehenden und ggf. auch neu dazukommenden Datensätzen. http://dev.mysql.com/doc/refman/5.0/en/insert-on-duplicate.html
Wenn das alles nichts ist, und tatsächlich ein SELECT mit nachfolgendem INSERT sein muß, läßt sich diese Konstruktion nur dann sicher verwenden, wenn du Transaktionen benutzt. Das macht die Sache aber gleich eine ganze Stufe komplexer.
- Sven Rautenberg
"Love your nation - respect the others."