• Jetzt anmelden. Es dauert nur 2 Minuten und ist kostenlos!

Rows affected ist nicht eindeutig

achtelpetit

Neues Mitglied
Guten Tag zusammen,
bekanntlich liefert MySQL nichts zurück, wenn eine Update-Abfrage in einem Datensatz schon den Wert vorfindet, den man updaten will.
Weil ich aber eine Fallunterscheidung brauche (update oder insert) kann dieses Verhalten zu Fehlern führen, nämlich dann, wenn ich versuche einen schon vorhandenen DS anzufügen, nachdem "Rows affected" nichts gesagt hat.
Gibt es eine elegantere Möglichkeit, dieses Verhalten zu umschiffen, als zunächst einen Select auf den fraglichen DS auszuführen?
 
Werbung:
Danke für Deine Antwort. Ist schon klar, daß es sich um ein Mysql-Problem handelt, deshalb hab' ich ja die Frage in diesem Teil des Forums gestellt.
Replace ist allerdings auch keine gute Lösung, denn ich will nur einen Wert in einem DS updaten, die anderen bleiben unberührt. Ich müßte also zunächst die alten Werte auslesen, den einen aktualisieren und dann alles zurückschreiben. Damit ist ja nix gespart.
Meine Aufgabe ist
einen Datensatz entweder updaten (falls vorhanden) oder inserten (falls noch nicht vorhanden).
Mein Plan war: Update ausführen - wenn 1 DS affected ist - dann Ende - wenn 0 DS affected - dann Insert
Nun kann es aber vorkommen, daß der neue Wert gleich dem alten ist. Folge: es wird ein Insert mit demselben Primärschlüssel versucht - Folge: Bumm.
 
Werbung:
denn ich will nur einen Wert in einem DS updaten, die anderen bleiben unberührt. Ich müßte also zunächst die alten Werte auslesen, den einen aktualisieren und dann alles zurückschreiben. Damit ist ja nix gespart.
Meine Aufgabe ist
einen Datensatz entweder updaten (falls vorhanden) oder inserten (falls noch nicht vorhanden).
Mein Plan war: Update ausführen - wenn 1 DS affected ist - dann Ende - wenn 0 DS affected - dann Insert
Nun kann es aber vorkommen, daß der neue Wert gleich dem alten ist. Folge: es wird ein Insert mit demselben Primärschlüssel versucht - Folge: Bumm.
Wieso machst du ein insert mit einem Primärschlüssel?
Du musst auch keinen ganzen Datensatz updaten, es reicht das betroffene Feld. Wenn du einen Update ausführen willst, gehe ich mal davon aus, dass du vorher sowieso die Daten gezogen hast. Du brauchst ja die ID. Insofern kannst du auch im Skript schon prüfen, ob der Datensatz existiert oder erneuert werden muss. Wieso willst du das unbedingt mysql anlasten?
 
Du musst auch keinen ganzen Datensatz updaten, es reicht das betroffene Feld
Ja freilich, das ändert aber nix daran, daß auch dann bei Rows affected unter Umständen nix zurückkommt.

Du brauchst ja die ID
Ja freilich, wie soll ich sonst den DS identifizieren?

Insofern kannst du auch im Skript schon prüfen, ob der Datensatz existiert oder erneuert werden muss.
Ja freilich, das ist ja die Fragestellung: muß ich zunächst einen Select machen und dann entscheiden ob Update oder Insert oder gibt es eine elegantere Lösung?
Sowenig Code wie möglich bei größter Sicherheit des logischen Ablaufs, das ist mein Ziel.
 
Ja freilich, das ist ja die Fragestellung: muß ich zunächst einen Select machen und dann entscheiden ob Update oder Insert oder gibt es eine elegantere Lösung?
Sowenig Code wie möglich bei größter Sicherheit des logischen Ablaufs, das ist mein Ziel.
Ich verstehe deine Frage nicht.

Du machst doch bereits einen Select um an die Daten zukommen, was sollte denn eleganter sein, als mit diesen Daten zu entscheiden ob du einen Update oder Insert machen musst?
Zumal die Entscheidung ja ganz Trivial ist, wenn die Daten eine ID haben, musst du einen update machen.
 
Werbung:
Okay, der Ablauf ist folgender:
Folgendes geht NICHT jedenfalls nicht immer, weil der Update-Wert auch zufällig der alte Wert sein kann und dann eben nix affected ist
(Das Verfahren war ich so aber gewohnt von der Jet-Engine)
Update ausführen
- wenn RowsAffected = 1
- Ende der Aktion
else wenn RowsAffected = 0
- Insert ausführen
Das heißt im 1 Abfrage wenn DS vorhanden oder 2 Abfragen wenn DS nicht vorhanden

Folgendes geht
Select ausführen
- wenn DS vorhanden
- Update ausführen
- wenn DS nicht vorhanden
- Insert ausführen
Das heißt immer 2 Abfragen, egal ob DS vorhanden oder nicht
 
Okay, der Ablauf ist folgender:
Folgendes geht NICHT jedenfalls nicht immer, weil der Update-Wert auch zufällig der alte Wert sein kann und dann eben nix affected ist
(Das Verfahren war ich so aber gewohnt von der Jet-Engine)
Update ausführen
- wenn RowsAffected = 1
- Ende der Aktion
else wenn RowsAffected = 0
- Insert ausführen
Das heißt im 1 Abfrage wenn DS vorhanden oder 2 Abfragen wenn DS nicht vorhanden
Nein, eine Abfrage um die Daten zu bekommen und eine wenn du die Daten updaten musst. Ich weiß nicht, wie du updaten willst ohne eine Abfrage welche ID du benutzt. Das heißt rowsAffected ist für dich völlig unrelevant.
 
Ich weiß nicht, wie du updaten willst ohne eine Abfrage welche ID du benutzt

Wenn da ein Haufen Leute steht und ich suche Rumpelstilzchen, dann frage ich doch in die Menge der Leute nach Rumpelstilzchen. Das geht doch nur, wenn ich vorher weiß, wen ich suche.
 
Werbung:
Wenn da ein Haufen Leute steht und ich suche Rumpelstilzchen, dann frage ich doch in die Menge der Leute nach Rumpelstilzchen. Das geht doch nur, wenn ich vorher weiß, wen ich suche.
Irgendwie wird mir deine Logik nicht klarer.

Du kannst kein update machen, wenn du keine ID hast. Also hast du mir vorhin bestätigt, dass du dir die ID holst. Damit ist die erste Abfrage gemacht. Du hast die ID und kannst diese beim eingeben der Daten auch übermitteln. Folglich kannst du danach den update mit dieser ID machen. Wenn du keine ID hast, dann machst du eben den Insert. In der Form: if($ID) update($daten); else insert($daten);
 
Ich kenne die ID.
Ich weiß aber nicht, ob es diese ID schon in der Tabelle gibt.

Noch einfacher als in #7 kann ich's nicht beschreiben.
 
Werbung:
Woher kennst du die ID, wenn diese nicht in der Tabelle ist? Das ist unlogisch.
Nein, das ist normal in einer DB. Wenn ich eine Tabelle abfrage, weiß ich prinzipiell nicht, ob der abgefragte Wert in der Tabelle vorhanden ist.
Kann es sein, dass du die IDs selbst erfindest?
Ja, es sind Session-ids.
Dann ist dein Datenbankschema unsauber.
Nein, die DB ist sauber.
 
Nein, das ist normal in einer DB. Wenn ich eine Tabelle abfrage, weiß ich prinzipiell nicht, ob der abgefragte Wert in der Tabelle vorhanden ist.
Was soll das denn? Natürlich weißt du das, du bekommst ja eine Antwort. Irgendwie sprechen wir eine andere Sprache.

Ja, es sind Session-ids.
Das ist zwar nicht ganz sauber, kann man aber machen. Aber weißt du nicht, ob die Session gerade erzeugt wurde (insert) oder nicht?

Ansonsten bleibt dir gar keine andere Möglichkeit, als jedes Mal die Tabelle abzufragen.

Bzw. was gehen könnte ist ein Timestampfeld, dass sollte sich doch automatisch ändernd und vielleicht auf das Ergebnis wirken.
 
Werbung:
Nachdem ich die Antwort bekommen habe, weiß ich, ob der Wert da ist.
Wenn ich die Abfrage starte, weiß ich noch nicht, ob der abgefragte Wert vorhanden ist.

Offenbar
Ja sicher, aber die Abfrage steht ja nicht im leeren Raum, sondern du bekommst immer eine Antwort, also weißt du, wenn du eine Abfrage [in deinem Skript] startest, ob die ID vorhanden ist oder nicht.
 
Richtig, und damit sind wir wieder bei der Frage, mit der ich den Thread eröffnet habe.
Im Falle einer Update-Abfrage ist die Antwort nicht eindeutig.
Da haben wir den Unterschied. Eine Abfrage ist für mich ein SELECT ..... WHERE id = .... und dann ist die Antwort eindeutig.

Wir haben aber trotzdem jetzt unzählige Beiträge gebraucht, um zu klären woher du die ID weisst und du gar keine Abfrage machst sondern nur ein update. Das war aus deinen Posting nicht zu erkennen. Eine ID in der Datenbank wird ja normalerweise automatisch erstellt und sollte bei einem Update schon zu Verfügung stehen, da du ein update nur machen kannst, wenn du die ID aus der Datenbank geholt hast.

Und ich habe dir auch schon einen Lösung vorgeschlagen, aber stattdessen reitest du auf deiner Deutung von Abfrage und Antwort rum. Mir ist das JETZT klar, was du machst. aber was ist mit meinem Vorschlag?

EDIT: ich hab noch mal alles durchgelesen, das Problem ist das du nicht auf meine erste Frage eingegangen bist. Ich hatte dich doch gefragt woher du die ID hast. Ausser deinem "Ja, freilich" kam da aber nichts, also ging ich davon aus, dass du einen select vorher machst.
 
Werbung:
Zurück
Oben