Я импортирую большое количество больших файлов в несколько таблиц, которые должны быть разбиты с помощью циклов внутри блока анонимного кода 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
не работает в хранимых функциях, поскольку вся функция обрабатывается как одна транзакция.
Блок кода обрабатывается так, как если бы это было тело функции без параметров, возвращая void. Он анализируется и выполняется один раз.
Я предполагаю, что это означает, что вся $do$
транзакция одна, и поэтому фиксация внутри блока не будет работать. Я прав?
BEGIN
илиCOMMIT
в теле функции. Вы получите исключение, потому что это не разрешено (невозможно).Ответы:
Нет,
Вы не можете контролировать транзакцию внутри
plpgsql
функции (или анонимного блока).Единственный вариант, когда у вас есть создание транзакции вне блока, например:
Кстати,
DO BLOCKS
имеют тот же эффект, что и функции, которые возвращаютсяvoid
.Пожалуйста, смотрите больше в документе:
источник
Единственное решение для фиксации в блоках (или функциях) DO (для версии Postgresql менее 11) - это использовать соединение dblink с тем же сервером и выполнять там ваши запросы. Просто имейте в виду переменные и временные объекты видимости.
дополнительная информация о dblink Начиная с Postgresql-11, управление транзакциями изнутри блока «DO» доступно, в то время как «DO-блок» не выполняется в другой транзакции.
источник
dblink
вами откроет еще одну транзакцию, поэтому вашCOMMIT
звонок там не повлияет на транзакцию вызова, если я не ошибаюсь.