Re: MySQL: affected_rows treibt mich in den Wahnsinn

[email protected] (Jan Trippler)
Newsgroups gmane.linux.suse.programming
Message-ID <[email protected]>
Am Montag, 29. November 2004 22:03 schrieb Joerg Rossdeutscher:
> Per php möchte ich in MySQL
> - den Wert eines Feldes ÄNDERN, wenn es bereits existiert,
> - oder einen entsprechenden Datensatz HINZUFÜGEN, wenn das Feld
>   noch nicht exisitierte.
>
> Sprich, auf gut hochdeutsch: Hinterher soll da stehen:
>
> Eindeutige ID: 13
> Name: Ratti
>
> ...egal, ob es die "13" vorher schon gab und welchen Wert "Name"
> hatte. Mein Problem: Es soll auch dann klappen, wenn beides
> bereits vorher exakt so vorhanden war!
>
> Ich habe sowas im Einsatz, Pseudocode, ungequotet:
>
> UPDATE SET name="ratti" WHERE id=13
> if mysql_affected_rows == 0 {
> 	INSERT SET name="ratti" , id=13
> }
>
> Das klappt in allen Fällen - AUSSER, wenn der Datensatz vorher
> schon genau so aussah, denn affected_rows meldet nur die
> tatsächlich veränderten Datensätze zurück (Bin ich alleine mit
> der Meinung, daß das total bescheuert ist?). In diesem Fall
> bekomme ich eine 0 geliefert, der nächste Befehl liefert mir dann
> einen Fehler, weil die id als UNIQUE deklariert ist - was auch
> korrekt ist.
>
> Da die Datenbank sehr groß ist, kommt es nicht in Frage, vorher
> mit SELECT die Werte auszugraben und zu gucken, was man tun muß.
>
> Da das ganze auch auf älteren Distris laufen soll, kommt
> ebenfalls nicht in Frage INSERT ... ON DUPLICATE KEY UPDATE zu
> verwenden, weil das ab MySQL 4.1 und somit zu neu ist.
>
> Für REPLACE finde ich leider nicht heraus, seit wann das drin ist
> - und ehrlich gesagt, ich begreife nicht, was genau es denn nun
> ersetzt und was nicht.

Replace macht eigentlich genau das, was Du willst:
<schnipp>
REPLACE works exactly like INSERT, except that if an old record in 
the table has the same value as a new record for a PRIMARY KEY or a 
UNIQUE index, the old record is deleted before the new record is 
inserted.
<schnapp>

Also macht replace ein Insert, außer wenn der PK bereits existiert, 
dann macht er zuerst ein Delete auf den betreffenden Satz und dann 
ein Insert.

Du kannst aber auch wie folgt vorgehen, wenn das "IGNORE" bereits 
Bestandteil früherer Versionen ist:
UPDATE IGNORE tabelle SET ... WHERE id = 13;
INSERT IGNORE INTO tabelle (...) VALUES (...);

IGNORE bricht nicht ab, wenn es auf einen Fehler trifft.

Jan

P.S.: Ich weiss nicht, woher Deine einzufügenden Daten stammen - 
wenn sie aus einer Datei kommen, solltest Du Dir mal LOAD DATA 
anschauen - ist deutlich schneller als Inserts oder Updates.

-- 
Linux-Quickies: http://www.jan-trippler.de
PingoS: http://www.pingos.org

-- 
Um die Liste abzubestellen, schicken Sie eine Mail an:
    [email protected]
Um eine Liste aller verfügbaren Kommandos zu bekommen, schicken
Sie eine Mail an: [email protected]
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.