Page 1 sur 1

Afficher la progression d'un traitement en PL/SQL et PL/pgSQL

Posté : mer. 12 sept. 2018 16:04
par Phil
Merci à Richard pour sa question :

"J'aimerais afficher la progression d'un traitement effectué en PL à l'utilisateur au fur et à mesure. Est-ce possible avec Oracle et PostgreSQL ?"

Réponse :
Avec Oracle Database, c'est compliqué mais il existe des solutions : https://asktom.oracle.com/pls/apexf?p=1 ... 0346426646
Avec PostgreSQL, c'est direct.
Exemple de bloc anonyme PL/pgSQL affichant un message à chaque tour de boucle :

Code : Tout sélectionner


select version();
                                                 version
----------------------------------------------------------------------------------------------------------
 PostgreSQL 9.6.9 on x86_64-pc-linux-gnu, compiled by gcc (Debian 6.3.0-18+deb9u1) 6.3.0 20170516, 64-bit
(1 ligne)

do
$$
begin
for i in 1..10 loop
perform pg_sleep(1);
RAISE NOTICE 'Salut Richard !, %', i;
end loop;
end$$;

Afficher (ou enregistrer) la progression d'un traitement en PL/SQL et PL/pgSQL

Posté : mar. 9 oct. 2018 11:34
par Phil
Merci à un DBA Oracle pour sa question :

"OK on peut afficher la progression directement. Mais on ne peut pas faire commit dans du PL avec PostgreSQL donc c'est quand même bien limité si on veut enregistrer la progression d'un traitement dans une table même s'il on l'annule finalement..."

Réponse :

Un peu de patience, ce n'est plus vrai depuis PostgreSQL 11, dans les procédures https://pgphil.ovh/procedure_11_beta_01.php comme dans les blocs anonymes.
Petit exemple :

Code : Tout sélectionner

select version();
                                                               version
-------------------------------------------------------------------------------------------------------------------------------------
 PostgreSQL 11beta3 (Debian 11~beta3-2~666.git7a42223.pgdg+1) on x86_64-pc-linux-gnu, compiled by gcc (Debian 8.2.0-4) 8.2.0, 64-bit
(1 ligne)

create table t1(c1 int, c2 timestamp);
CREATE TABLE

create table t2(c1 int, c2 timestamp);
CREATE TABLE

do
$$
begin
for i in 1..10 loop
	perform pg_sleep(1);
	RAISE NOTICE 'Salut !, %', i;
	insert into t1 values(i, clock_timestamp());
	if (select mod(max(c1),2)=0 from t1) then
		rollback;
		insert into t2(c1, c2) values(i, clock_timestamp());
	end if;
	commit;
end loop;
end$$;
NOTICE:  Salut !, 1
NOTICE:  Salut !, 2
NOTICE:  Salut !, 3
NOTICE:  Salut !, 4
NOTICE:  Salut !, 5
NOTICE:  Salut !, 6
NOTICE:  Salut !, 7
NOTICE:  Salut !, 8
NOTICE:  Salut !, 9
NOTICE:  Salut !, 10
DO


table t1;
 c1 |             c2
----+----------------------------
  1 | 2018-10-09 09:30:54.189659
  3 | 2018-10-09 09:30:56.195938
  5 | 2018-10-09 09:30:58.200679
  7 | 2018-10-09 09:31:00.205469
  9 | 2018-10-09 09:31:02.210257
(5 lignes)


table t2;
 c1 |             c2
----+----------------------------
  2 | 2018-10-09 09:30:55.193502
  4 | 2018-10-09 09:30:57.198506
  6 | 2018-10-09 09:30:59.203282
  8 | 2018-10-09 09:31:01.207848
 10 | 2018-10-09 09:31:03.214138
(5 lignes)