Могу ли я попросить Postgresql игнорировать ошибки в транзакции
Я использую Postgresql с расширениями PostGIS для пространственного анализа ad-hoc. Я обычно создаю и выдаю SQL-запросы вручную из psql. Я всегда завершаю сеанс анализа внутри транзакции, поэтому, если я выдаю деструктивный запрос, я могу отбросить его назад.
Однако, когда я выдаю запрос, содержащий ошибку, он отменяет транзакцию. Любые дополнительные запросы вызывают следующее предупреждение:
ОШИБКА: текущая транзакция прерывается, команды игнорируются до конца блок транзакций
Есть ли способ отключить это поведение? Очень утомительно откатывать транзакцию и повторять предыдущие запросы каждый раз, когда я делаю опечатку.
Ответы
Ответ 1
(ОБНОВЛЕНИЕ: мне не нужно этого вручную, я спросил в списках рассылки postgresql, и оказалось, что это поведение уже реализовано с помощью ON_ERROR_ROLLBACK установлен в клиенте psql)
Чтобы уточнить ответ Саймона (+1), в вашем сценарии вы могли бы вручную добавить точку сохранения после каждого интерактивного запроса, всегда с тем же именем (он овещает предыдущий, если запрос является успешным). В случае ошибки вы возвращаетесь к последнему сохраненному и продолжаете оттуда.
Пример этого рабочего шаблона:
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)
Ответ 2
Выключение этого параметра невозможно, но вы можете использовать что-то другое. Есть что-то вроде точки сохранения:
http://www.postgresql.org/docs/8.4/interactive/sql-savepoint.html
чтобы вы могли отменить свою транзакцию до более ранней точки, не перевернув всю транзакцию.
Ответ 3
Нет, нет способа отключить это. Ошибка неявно отменяет транзакцию для вас, поэтому вам нужно выполнить откат и повторить попытку.
Ответ 4
Можно написать функцию, которая принимает строковый аргумент, выполняет его и использует exception, чтобы не прерывать транзакцию, но это огромная боль, чтобы затем вызвать эту функцию для каждого оператора, который вы хотите выполнить.
Ответ 5
Простым ответом является запуск
my_db=> \set ON_ERROR_ROLLBACK interactive
в интерактивном сеансе. См. Также этот пост в блоге своим разработчиком.