2010-04-30 2 views
11

Ich verwende Postgresql mit den PostGIS-Erweiterungen für räumliche Ad-hoc-Analysen. Ich konstruiere und gebe SQL-Abfragen in der Regel von Hand innerhalb von psql aus. Ich schliesse immer eine Analysesitzung innerhalb einer Transaktion. Wenn ich also eine destruktive Abfrage ausstelle, kann ich sie zurückrollen.Kann ich Postgresql bitten, Fehler innerhalb einer Transaktion zu ignorieren?

Wenn ich jedoch eine Abfrage, die einen Fehler enthält, ausstelle, wird die Transaktion abgebrochen. Bei weiteren Abfragen wird folgende Warnung ausgelöst:

Gibt es eine Möglichkeit, dieses Verhalten auszuschalten? Es ist mühsam, die Transaktion rückgängig zu machen und vorherige Abfragen jedes Mal erneut auszuführen, wenn ich einen Tippfehler mache.

Antwort

10

(UPDATE: Keine Notwendigkeit, um diese von Hand, fragte ich in den postgresql Mailinglisten, und es stellte sich, dass dieses Verhalten bereits implementiert ist, durch die ON_ERROR_ROLLBACK Satz in der psql)

auf Simons zu erarbeiten Antwort (+1), in Ihrem Szenario könnten Sie nach jeder interaktiven Abfrage automatisch einen Sicherungspunkt hinzufügen, immer mit dem gleichen Namen (überschreibt den vorherigen, wenn die Abfrage erfolgreich ist). Im Fehlerfall gehen Sie zurück zum zuletzt gespeicherten und fahren von dort fort.

Ein Beispiel für diese Arbeitsmuster:

db=# select * from test_gral ; 
i | t | n 
---+------+------ 
1 | text | 10.0 
(1 row) 

db=# begin; 
BEGIN 
db=# insert into test_gral values (2,'xx',20); savepoint sp; 
INSERT 0 1 
SAVEPOINT 
db=# insert into test_gral values (3,'xx',30); savepoint sp; 
INSERT 0 1 
SAVEPOINT 
db=# insert into test_gralxx values (4,'xx',40); savepoint sp; 
ERROR: relation "test_gralxx" does not exist 
LINE 1: insert into test_gralxx values (4,'xx',40); 
        ^
ERROR: current transaction is aborted, commands ignored until end of transaction block 
db=# ROLLBACK TO SAVEPOINT sp; 
ROLLBACK 
db=# insert into test_gral values (4,'xx',40); savepoint sp; 
INSERT 0 1 
SAVEPOINT 
db=# commit; 
COMMIT 
db=# select * from test_gral ; 
i | t | n 
---+------+------ 
1 | text | 10.0 
2 | xx | 20 
3 | xx | 30 
4 | xx | 40 
(4 rows) 
+0

die ON_ERROR_ROLLBACK-Variable macht genau das, was ich wollte :) – fmark

+0

'ON_ERROR_ROLLBACK' sieht aus wie eine Funktion des psql-Clients, nicht selbst postgres (also kann man dies nicht aus einer Datenbankanwendung heraus verwenden, nur von der Kommandozeile aus). – Glyph

+1

@Glyph: Ja, das ist ein Feature für psql, es ist speziell auf interaktive Nutzung ausgerichtet - das war das OP-Szenario. Es ist schwierig für mich, an ein Anwendungsszenario zu denken, wenn das gewünschte Verhalten Sinn machen würde. – leonbloy

2

Nein, es gibt keine Möglichkeit, dies auszuschalten. Ein Fehler bricht die Transaktion implizit für Sie ab, daher müssen Sie ein Rollback durchführen und es erneut versuchen.

+0

+1 tatsächlich (15 Zeichen) –

+0

dachte ich auch, aber nein. Siehe meine Antwort. – leonbloy

1

Es ist möglich, eine Funktion zu schreiben, die ein String-Argument executes verwendet und eine exception-Klausel verwendet, um Ihre Transaktion nicht abzubrechen, aber es ist ein großer Schmerz, diese Funktion dann für jede gewünschte Anweisung aufrufen zu müssen ausführen.

0

Die einfache Antwort ist

my_db=> \set ON_ERROR_ROLLBACK interactive 

in der interaktiven Sitzung auszuführen. Siehe auch this blog post von seinem Hersteller.