Wie kann ich ein Postgres-Skript stoppen, wenn ein Fehler auftritt?

95

Gibt es eine Möglichkeit anzugeben, dass beim Ausführen eines SQL-Skripts der erste Fehler im Skript gestoppt wird, der normalerweise fortgesetzt wird, unabhängig von vorherigen Fehlern.

Strahl
quelle

Antworten:

156

Ich denke, die Lösung, um .psqlrc Folgendes hinzuzufügen, ist alles andere als perfekt

\set ON_ERROR_STOP on

Es gibt eine viel einfachere und bequemere Möglichkeit - verwenden Sie psql mit dem Parameter:

psql -v ON_ERROR_STOP=1

Besser ist es auch, -XParameter zu verwenden, die die Verwendung von .psqlrc-Dateien deaktivieren. Funktioniert perfekt für mich

ps die Lösung in großem Beitrag von Peter Eisentraut gefunden. Danke, Peter! http://petereisentraut.blogspot.com/2010/03/running-sql-scripts-with-psql.html

Alfishe
quelle
8
-v ON_ERROR_STOP=ONfunktioniert auch, zumindest mit 9.2. Ich vermute, dass eine der Varianten von boolean "true" erlaubt ist.
jpmc26
Es funktioniert nicht im interaktiven Modus, was mich für eine Minute verwirrte.
Sam Watkins
20

Ich gehe davon aus, dass Sie verwenden psql, dies könnte nützlich sein, um es Ihrer ~/.psqlrcDatei hinzuzufügen .

\set ON_ERROR_STOP on

Dadurch wird es beim ersten Fehler abgebrochen. Wenn Sie es nicht haben, führt es auch bei einer Transaktion Ihr Skript weiter aus, schlägt jedoch bis zum Ende Ihres Skripts bei allem fehl.

Und Sie möchten wahrscheinlich eine Transaktion verwenden, wie Paul sagte. Dies ist auch möglich, psql --single-transaction ...wenn Sie das Skript nicht ändern möchten.

Ein vollständiges Beispiel mit ON_ERROR_STOP in Ihrer .psqlrc:

psql --single-transaction --file /your/script.sql
Plundra
quelle
2
Selbst wenn die Transaktion fehlschlägt, ist der Exit-Status des Befehls psql immer noch 0.
Dr. Person Person II
4
Selbst wenn --single-transactiones verwendet wird, -v ON_ERROR_STOP=1ist es dennoch notwendig, dass ein Status ungleich Null existiert
Bitek
7

Es ist nicht genau das, was Sie wollen, aber wenn Sie Ihr Skript mit beginnen begin transaction;und damit enden end transaction;, wird tatsächlich alles nach dem ersten Fehler übersprungen und dann wird alles zurückgesetzt, was es vor dem Fehler getan hat.

Paul Tomblin
quelle
Stimmt, aber es analysiert immer noch alles. Und wenn Sie eine zweite Transaktion nur durchführen möchten, wenn die erste erfolgreich war, funktioniert dies nicht.
Wildcard
Ja, und nicht zu vergessen, wenn Sie auf DDL stoßen. Erstellen Sie Tabellenfehler ... (Version: postrgres 10). Ja, es überspringt einen Tisch und geht auf die anderen ...
JL Peyret
0

Ich verweise immer gerne direkt auf das Handbuch.

Aus dem PostgreSQL-Handbuch :

Status beenden

psql gibt 0 an die Shell zurück, wenn sie normal beendet wurde, 1, wenn ein schwerwiegender Fehler auftritt (z. B. nicht genügend Speicher, Datei nicht gefunden), 2, wenn die Verbindung zum Server unterbrochen wurde und die Sitzung nicht interaktiv war, und 3, wenn In einem Skript ist ein Fehler aufgetreten und die Variable ON_ERROR_STOP wurde gesetzt.

Standardmäßig beendet psql keinen Fehler, wenn der SQL-Code, den Sie auf dem PostgreSQL-Server ausführen, psql nicht beendet. Es wird den Fehler abfangen und fortfahren. Wenn Sie, wie oben erwähnt, die ON_ERROR_STOPEinstellung auf on setzen und psql einen Fehler im SQL-Code abfängt, wird es beendet und kehrt 3zur Shell zurück.

Gregory Arenius
quelle