Un COMMIT funziona all'interno di una funzione anonima plgpsql in PostgreSQL 9.5?


8

Sto importando un gran numero di file di grandi dimensioni in un numero di tabelle da partizionare usando loop all'interno di un blocco di codice plpgsql anonimo $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'intero processo dovrebbe richiedere circa 15 ore e spero che tutte le importazioni non vengano ripristinate in caso di errore di importazione a un certo punto.

IIRC COMMITnon funziona con le funzioni memorizzate perché l'intera funzione viene trattata come una singola transazione.

Dalla documentazione per$do$

Il blocco di codice viene trattato come se fosse il corpo di una funzione senza parametri, restituendo vuoto. Viene analizzato ed eseguito una sola volta.

Suppongo che questo significhi che l'intera $do$è una transazione, quindi i commit all'interno del blocco non funzioneranno. Ho ragione?


1
Prova BEGINo COMMITnel corpo della funzione. Otterrai un'eccezione, perché ciò non è consentito (non possibile).
Erwin Brandstetter,

Risposte:


9

No,

Non puoi controllare una transazione all'interno di una plpgsqlfunzione (o blocco anonimo).

L'unica opzione che hai è la creazione di una transazione al di fuori del blocco, ad esempio:

BEGIN;

DO $$
  -- function stuff

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

COMMIT; -- OR ROLLBACK

A proposito, DO BLOCKShanno lo stesso effetto che funziona chi ritorna void.

Per favore, vedi di più sul documento:


Sappiamo se è ancora così? Ho una funzione che deve essere ripetuta diverse centinaia di volte. Il primo ciclo dura 2 secondi dopo che il 7 ° è quasi un'ora e non ho visto nulla dopo il 10 ° ciclo.
Dennis Bauszus,

1

L'unica soluzione per eseguire il commit all'interno di blocchi (o funzioni) "DO" (per la versione Postgresql inferiore a 11) è utilizzare la connessione dblink allo stesso server ed eseguire le query lì. Ricorda solo la visibilità delle variabili e degli oggetti temporanei.

maggiori informazioni su dblink A partire da Postgresql-11 è disponibile il controllo delle transazioni dall'interno del blocco "DO" mentre "Blocco DO" non è in esecuzione all'interno di altre transazioni.


postgresql.org/docs/11/sql-do.html afferma "Le dichiarazioni di controllo delle transazioni sono consentite solo se DO viene eseguito nella propria transazione". Questo ovviamente non era vero con 9.5. OTOH con dblinkte aprirà un'altra transazione, quindi la tua COMMITchiamata non influirà sulla transazione chiamante, se non sbaglio.
dezso

Colpa mia. Il controllo delle transazioni all'interno di "DO" è stato introdotto in Postgresql-11. Controllo solo il 10.4 ancora non funziona.
Dzhureedzh,

@dezso Grazie per avermi indicato questo, stavo usando il metodo dblink anche su server PG11.
Dzhureedzh,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.