Работает ли COMMIT в анонимной функции plgpsql в PostgreSQL 9.5?


8

Я импортирую большое количество больших файлов в несколько таблиц, которые должны быть разбиты с помощью циклов внутри блока анонимного кода plpgsql $do$.

$do$
BEGIN
    FOR yyyy in 2012..2016 THEN 
        EXECUTE $$COPY table$$||yyyy||$$ FROM 'E:\data\file$$||yyyy||$$.csv DELIMITER ',' CSV;$$;
    END LOOP;
END;
$do$ LANGUAGE plpgsql

Весь этот процесс должен занять около 15 часов, и я надеюсь, что весь импорт не будет отменен, если в какой-то момент произойдет ошибка импорта.

IIRC COMMITне работает в хранимых функциях, поскольку вся функция обрабатывается как одна транзакция.

Из документации для$do$

Блок кода обрабатывается так, как если бы это было тело функции без параметров, возвращая void. Он анализируется и выполняется один раз.

Я предполагаю, что это означает, что вся $do$транзакция одна, и поэтому фиксация внутри блока не будет работать. Я прав?


1
Попробуй BEGINили COMMITв теле функции. Вы получите исключение, потому что это не разрешено (невозможно).
Эрвин Брандштеттер,

Ответы:


9

Нет,

Вы не можете контролировать транзакцию внутри plpgsqlфункции (или анонимного блока).

Единственный вариант, когда у вас есть создание транзакции вне блока, например:

BEGIN;

DO $$
  -- function stuff

  -- but if you use a exception, you will force a rollback
  RAISE EXCEPTION 'message';
$$ LANGUAGE 'plpgsql';

COMMIT; -- OR ROLLBACK

Кстати, DO BLOCKSимеют тот же эффект, что и функции, которые возвращаются void.

Пожалуйста, смотрите больше в документе:


Мы знаем, так ли это на самом деле? У меня есть функция, которая должна зацикливаться несколько сотен раз. Первый цикл занимает 2 секунды после того, как 7-й близок к часу, и я ничего не видел после 10-го цикла.
Деннис Баусус

1

Единственное решение для фиксации в блоках (или функциях) DO (для версии Postgresql менее 11) - это использовать соединение dblink с тем же сервером и выполнять там ваши запросы. Просто имейте в виду переменные и временные объекты видимости.

дополнительная информация о dblink Начиная с Postgresql-11, управление транзакциями изнутри блока «DO» доступно, в то время как «DO-блок» не выполняется в другой транзакции.


postgresql.org/docs/11/sql-do.html утверждает, что «операторы управления транзакциями разрешены, только если DO выполняется в своей собственной транзакции». Это было, конечно, не так с 9,5. OTOH с dblinkвами откроет еще одну транзакцию, поэтому ваш COMMITзвонок там не повлияет на транзакцию вызова, если я не ошибаюсь.
Дезсо

Виноват. Контроль транзакций в рамках «DO» был введен в Postgresql-11. Я просто проверяю на 10.4 все еще не работает.
Джуредж

@dezso Спасибо, что указали мне на это, я использовал метод dblink даже на серверах PG11.
Джуредж
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.