Чи працює 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не працює в межах збережених функцій bc, вся функція трактується як одна транзакція.

З документації для$do$

Блок коду трактується так, ніби він є тілом функції без параметрів, повертаючи порожнечу. Він розбирається і виконується одноразово.

Я припускаю, що це означає, що вся $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.3. OTOH з dblinkвами відкриє ще одну транзакцію, тому ваш COMMITдзвінок там не вплине на транзакцію дзвінка, якщо я не помиляюся.
дезсо

Моє ліжко. Контроль транзакцій в межах "DO" було введено в Postgresql-11. Я просто перевіряю, що 10.4 все ще не працює.
Джуредж

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