2016-05-10 6 views
0

Zusammenfassung des Problems: Mit MySQL und SQLite, ein Fehler INSERT OR IGNORE auf einer Tabelle mit AUTOINCREMENT noch erhöht den autoinkrementierten Wert. Dies wurde hier diskutiert: INSERT IGNORE increases auto increment counter even no record is added?Kann AUTOINCREASE bei fehlgeschlagenem "INSERT OR IGNORE" verhindert werden?

Mein Problem: eine Tabelle mit 99% Einsätze gescheitert endet mit großen Indexzahlen, zum Beispiel Rekord 1500 hat den Index 165200.

Dies ist unpraktisch, so ich suche eine Möglichkeit, diesem Verhalten entgegenzuwirken.

Da INSERT OR IGNORE ist angeblich die gleiche wie INSERT ON CONFLICT IGNORE, habe ich gedacht INSERT ON CONFLICT FAIL oder INSERT ON CONFLICT ABORT verwenden.

Mein Problem ist, dass ich von einem SELECT auf diese Weise am Einfügen:

INSERT OR IGNORE INTO t1 (x,y,z,) SELECT * FROM t2

Diese Syntax nicht ON CONFLICT FAIL akzeptiert. Weder der beiden letztgenannten Arbeit:

INSERT ON CONFLICT FAIL INTO t1 (x,y,z,) SELECT * FROM t2

INSERT INTO t1 (x,y,z,) SELECT * FROM t2 ON CONFLICT FAIL

Irgendwelche Gedanken oder Hinweise?

Antwort

2

Zunächst ist on conflict nur für sqlite und wird verwendet, wenn Sie die Abhängigkeit definieren (z. B. ... primary key on conflict abort ...). abort wird keine Zeilen einfügen, wenn eine der Zeilen fehlschlägt. fail ist noch seltsamer: Wenn Sie versuchen, 5 Zeilen einzufügen und die dritte Zeile wegen der Schlüssel fehlschlägt, wird es die ersten 2 Zeilen einfügen und stoppt dann. Kurz gesagt: benutze es nicht. Beide Versionen sind NICHT identisch mit ignore (mindestens für mehr als eine Zeile).

Es gibt im Grunde nur eine Möglichkeit, das automatische Inkrementieren beim Einfügen mehrerer Zeilen zu verhindern: Fügen Sie keine Zeilen ein, die bereits in der Tabelle enthalten sind.

Der übliche Weg, dies zu tun, ist zu überprüfen, ob die Zeile für sich selbst statt der "faul" on duplicate key/ignore existiert. Z.B. für doppelte Werte in einer Spalte y zu überprüfen:

INSERT INTO t1 (x,y,z) 
SELECT * FROM t2 main 
where not exists (
    select * from t1 test 
    where main.y = test.y); 

Ja, ich weiß, es wird Ihren Code länger. Sie werden damit leider leben müssen.

+0

Hallo, vielen Dank für den Vorschlag. –