web-dev-qa-db-fra.com

Un COMMIT fonctionne-t-il dans une fonction plgpsql anonyme dans PostgreSQL 9.5?

J'importe un grand nombre de fichiers volumineux dans un certain nombre de tables à partitionner à l'aide de boucles dans un bloc de code plpgsql anonyme $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

L'ensemble de ce processus devrait prendre environ 15 heures et j'espère que toutes les importations ne seront pas annulées s'il y a une erreur d'importation à un moment donné.

IIRC COMMIT ne fonctionne pas dans les fonctions stockées bc la fonction entière est traitée comme une seule transaction.

De la documentation pour $do$

Le bloc de code est traité comme s'il s'agissait du corps d'une fonction sans paramètre, renvoyant void. Il est analysé et exécuté une seule fois.

Je suppose que cela signifie que l'ensemble $do$ est une transaction, et les validations dans le bloc ne fonctionneront donc pas. Ai-je raison?

8
raphael

Non,

Vous ne pouvez pas contrôler une transaction à l'intérieur d'une fonction plpgsql (ou d'un bloc anonyme).

La seule option que vous avez sa création d'une transaction en dehors du bloc, par exemple:

BEGIN;

DO $$
  -- function stuff

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

COMMIT; -- OR ROLLBACK

BTW, DO BLOCKS ont le même effet que les fonctions qui retournent void.

S'il vous plaît, voir plus sur le doc:

9
Sebastian Webber

La seule solution à valider dans des blocs (ou fonctions) "DO" (pour la version Postgresql inférieure à 11) est d'utiliser une connexion dblink au même serveur et d'y exécuter vos requêtes. Gardez simplement à l'esprit la visibilité des variables et des objets temporaires.

plus d'informations sur dblink À partir de Postgresql-11, le contrôle des transactions depuis l'intérieur du bloc "DO" est disponible pendant que "DO-block" ne s'exécute pas dans une autre transaction.

1
Dzhureedzh