Tu das nicht! NIEMALS ! Denken Sie nicht einmal daran!
Das ist FALSCH Die Lösung scheint (nicht) für Sie zu funktionieren:
INSERT INTO lists VALUES ((SELECT max(id)+1 FROM lists),'KO','SPH', '5');
ABER , wenn jemand versucht, gleichzeitig mit Ihnen einzufügen, würden Sie beide dieselbe id
erhalten , was zu einem ungültigen Ergebnis führt. Sie sollten wirklich eine sequence
verwenden oder ein zuverlässigerer Mechanismus (eine Hilfstabelle ist üblich, wenn Sie keine Löcher in der Sequenz haben können, aber sie hat einige Nachteile [sie wird gesperrt]). Sie können sogar serial
verwenden Datentyp, um es einfacher zu machen (erzeugt darunter eine Sequenz):
CREATE TABLE lists(id serial, col2 text, col3 text, ...);
-- If you don't specify "id", it will autogenerate for you:
INSERT INTO lists(col2, col3, ...) VALUES('KO','SPH', ...);
-- You can also specify using DEFAULT (the same as above):
INSERT INTO lists(id, col2, col3, ...) VALUES(DEFAULT, 'KO','SPH', ...);
Wenn Sie wirklich, wirklich, WIRKLICH keine Sequenz erstellen und verwenden können, können Sie wie oben beschrieben vorgehen, aber Sie müssen die Ausnahme behandeln (unter der Annahme, dass die id
das Feld PK oder UK ist und eine Read-Committed-Transaktion verwendet wird), etwa so (in PL/pgSQL):
DECLARE
inserted bool = false;
BEGIN
WHILE NOT inserted LOOP;
BEGIN
INSERT INTO lists
VALUES ((SELECT coalesce(max(id),0)+1 FROM lists),'KO','SPH', '5');
inserted = true;
EXCEPTION
WHEN unique_violation THEN
NULL; -- do nothing, just try again
END;
END LOOP;
END;
Aber noch einmal, ich empfehle Ihnen dringend, es zu vermeiden:Verwenden Sie eine Sequenz und seien Sie glücklich ... =D
Ich weiß auch, dass es sich um ein Beispiel handelt, aber verwenden Sie eine explizite Spaltenliste für INSERT INTO
Klausel.