匿名の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を返します。解析と実行は1回です。
これは、$do$
全体が1つのトランザクションであるため、ブロック内でのコミットが機能しないことを想定しています。私は正しいですか?
番号、
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
を返す関数と同じ効果があります。
詳しくはドキュメントをご覧ください:
「DO」ブロック(または関数)内でコミットする唯一の解決策(Postgresqlバージョンが11未満の場合)は、同じサーバーへのdblink接続を使用してそこでクエリを実行することです。変数と一時オブジェクトの可視性を覚えておいてください。
dblinkの詳細情報 Postgresql-11以降、「DOブロック」が他のトランザクション内で実行されていない場合でも、「DO」ブロック内からのトランザクション制御を使用できます。