PostgreSQL La base de donnees la plus sophistiquee au monde.

Forums PostgreSQL.fr

Le forum officiel de la communauté francophone de PostgreSQL

Vous n'êtes pas identifié(e).

#1 15/06/2015 16:43:10

ecpg - comment gérer les codes erreurs applicatifs

Bonjour.

j'ai un programme ecpg que je suis en train de porter sur PG.

son comportement initial est le suivant : il essaie d'insérer, et si l'enregistrement existe déjà, il fait un update.

begin transaction

exec sql insert into TABLE1 (CLE_PK, VALEUR) values ('A','fred');
# si le code erreur retourné vaut "duplicate key" alors je fais un update

if (sqlcode= 'dupkey' ) then
EXEC SQL UPDATE TABLE1 SET VALEUR='fred' WHERE CLE_PK='A';
end if;

EXEC SQL COMMIT;

Dans la pratique, je comprends que la première instruction qui renvoie un code erreur différent de zéro rollbacke toute la transaction.

je me vois mal devoir faire des select avant les insert afin d'éviter de tomber sur des erreurs.
y a t il un moyen de gérer les codes erreurs, sans "casser" la transaction embedded C ?
je vous remercie

Fred

Hors ligne

#2 15/06/2015 21:39:33

gleu
Administrateur

Re : ecpg - comment gérer les codes erreurs applicatifs

En dehors d'un savepoint, non. Mais je n'en vois pas l'intérêt vu que vous n'avez fait qu'une seule requête (à savoir, le INSERT). Et de toute façon, si vous faites un SELECT dans une transaction, cela ne vous garantit pas que l'insertion n'aura pas lieu la milli-seconde d'après par une autre session.


Guillaume.

Hors ligne

#3 16/06/2015 08:52:43

Re : ecpg - comment gérer les codes erreurs applicatifs

Bon, je me suis mal exprimé.
Soit une transaction faisant plusieurs ordres SQL en ecpg.
le 15eme ordre SQL fait un insert qui renvoie une erreur de type viloation de contrainte.
Comment faire en sorte de pouvoir gérer applicativement cette erreur et poursuivre la transaction jusqu'à un commit ?

sqlcode: -400
sqlerrm.sqlerrml: 124
sqlerrm.sqlerrmc: une instruction insert ou update sur la table « acelcothcl » viole la contrainte de clé
étrangère « acelacegfk » on line 276


Exemple  : voici ce que je souhaite faire :  si j'ai l'erreur ci-dessus, alors, je fais update puis je termine ma transaction.

Ce que je comprends actuellement, c'est que le 15eme ordre SQL qui part au tapis fiche en l'air toute la transaction, et qu'il n'y a plus qu'à faire un rollback(ou commit)  pour pouvoir continuer.
a la différence d'autres sgbd, où l'on peut gérer chaque code errreur sans qu'un rollback général se produise.

Autrement dit, une transaction doit être un "sans faute" sinon, il n'y a plus qu'à recommencer depuis le début.

j'ai tenté de gérer cela avec les WHENEVER

j'espère que ce sera plus clair, et que vous pourrez m'aider.

Merci

Fred

Hors ligne

#4 16/06/2015 21:14:51

gleu
Administrateur

Re : ecpg - comment gérer les codes erreurs applicatifs

Avez-vous essayé les SAVEPOINT ? c'est la seule solution à ma connaissance.


Guillaume.

Hors ligne

#5 18/06/2015 09:40:08

Re : ecpg - comment gérer les codes erreurs applicatifs

Bonjour Guillaume,
Effectivement, avec les savepoint, on s'en sort. Voici un exemple et le résultat sur psql

\set AUTOCOMMIT off

-- debut DDL
drop table fred;

create table fred (
cle     integer     not null,
libelle varchar(30) not null);

alter table fred add constraint fred_pk primary key (cle);
commit;

-- fin   DDL

-- debut DML
begin transaction;

insert into fred (cle, libelle ) values (10,'frederic');
insert into fred (cle, libelle ) values (20,'frederic');

-- on genere un plantage, pour continuer, il faut faire rollback;
savepoint CLE_DUPLIQUEE;
insert into fred (cle, libelle) values (10,'frederic');
rollback to savepoint CLE_DUPLIQUEE;

update fred set libelle='fred' where cle=10;

commit;

select * from fred order by 1;


DROP TABLE
CREATE TABLE
ALTER TABLE
COMMIT
BEGIN
INSERT 0 1
INSERT 0 1
SAVEPOINT
psql:test_transaction2.sql:23: ERREUR:  la valeur d'une clé dupliquée rompt la contrainte unique « fred_pk »
DÉTAIL : La clé « (cle)=(10) » existe déjà.
ROLLBACK
UPDATE 1
COMMIT
cle | libelle
-----+----------
  10 | fred
  20 | frederic
(2 lignes)

Hors ligne

Pied de page des forums