Jak mogę zatrzymać skrypt Postgres, gdy napotka błąd?

95

Czy istnieje sposób, aby określić, że podczas wykonywania skryptu sql zatrzymuje się po napotkaniu pierwszego błędu w skrypcie, zwykle kontynuuje, niezależnie od poprzednich błędów.

Promień
źródło

Odpowiedzi:

156

Myślę, że rozwiązanie dodawania następujących po .psqlrc jest dalekie od doskonałości

\set ON_ERROR_STOP on

istnieje dużo prostszy i wygodniejszy sposób - użyj psql z parametrem:

psql -v ON_ERROR_STOP=1

lepiej też używać -X parametru wyłączającego użycie pliku .psqlrc. U mnie działa idealnie

ps rozwiązanie znalezione w świetnym poście Petera Eisentrauta. Dziękuję, Peter! http://petereisentraut.blogspot.com/2010/03/running-sql-scripts-with-psql.html

Alfishe
źródło
8
-v ON_ERROR_STOP=ONdziała również, przynajmniej z 9.2. Podejrzewam, że każdy z wariantów wartości logicznej „prawda” jest dozwolony.
jpmc26
Nie działa w trybie interaktywnym, co przez chwilę zdezorientowało mnie.
Sam Watkins
21

Zakładam, że używasz psql, może to być przydatne do dodania do ~/.psqlrcpliku.

\set ON_ERROR_STOP on

Spowoduje to przerwanie pracy przy pierwszym błędzie. Jeśli go nie masz, nawet przy transakcji będzie wykonywał twój skrypt, ale zakończy się niepowodzeniem do końca skryptu.

I prawdopodobnie chcesz skorzystać z transakcji, jak powiedział Paul. Co również można zrobić, psql --single-transaction ...jeśli nie chcesz zmieniać skryptu.

A więc kompletny przykład, z ON_ERROR_STOP w twoim .psqlrc:

psql --single-transaction --file /your/script.sql
plundra
źródło
2
Nawet jeśli transakcja się nie powiedzie, status wyjścia polecenia psql nadal wynosi 0.
Dr Osoba II
4
Rzeczywiście, nawet jeśli --single-transactionjest używany, -v ON_ERROR_STOP=1nadal jest niezbędny dla statusu istnienia niezerowego
bitek
8

Nie jest to dokładnie to, czego chcesz, ale jeśli zaczniesz swój skrypt od begin transaction;i zakończysz end transaction;, w rzeczywistości pominie on wszystko po pierwszym błędzie, a następnie wycofa wszystko, co zrobił przed błędem.

Paul Tomblin
źródło
To prawda, ale nadal wszystko analizuje. A jeśli chcesz zrobić drugą transakcję tylko wtedy, gdy pierwsza się powiedzie, to nie zadziała.
Wildcard
Tak, i nie zapomnij kontynuować, gdy napotka błędy DDL Utwórz tabelę ... (wersja: postrgres 10). Tak, pomija jeden stolik i przechodzi do drugiego ...
JL Peyret,
0

Zawsze lubię odwoływać się bezpośrednio do instrukcji.

Z podręcznika PostgreSQL :

Status wyjścia

psql zwraca 0 do powłoki, jeśli zakończyło się normalnie, 1 jeśli wystąpił sam fatalny błąd (np. brak pamięci, nie znaleziono pliku), 2 jeśli połączenie z serwerem poszło źle, a sesja nie była interaktywna, a 3 jeśli wystąpił błąd w skrypcie i ustawiono zmienną ON_ERROR_STOP.

Domyślnie, jeśli kod sql uruchamiany na serwerze PostgreSQL błąd psql nie zamyka błędu. Wychwyci błąd i będzie kontynuował. Jeśli, jak wspomniano powyżej, ustawisz to ON_ERROR_STOPustawienie na włączone, kiedy psql wykryje błąd w kodzie sql, zakończy działanie i powróci 3do powłoki.

Gregory Arenius
źródło