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 11/02/2010 15:51:11

Patrick Sch
Membre

Problème avec une règle en INSERT

Bonjour,

J'ai mis en place 2 règles sur une grosse table pour éviter les problèmes d'index dupliqué, une règle Insert et une Update. La table est alimentée et mise à jour par des requêtes INSERT ou UPDATE avec plusieurs centaines de milliers d'enregistrements.

L'idée est de permettre à la requête d'aller jusqu'au bout, sans planter et faire un rollback. Pour ça, j'isole les lignes qui vont provoquer un index dupliqué, et j'écris dans une table d'anomalie, qui peut être ensuite analysée pour reprendre les pb manuellement.

Ça fonctionne bien pour la règle update, mais pas pour la règle insert ! S'il n'y a pas de pb d'index dupliqué, l'insert fonctionne, mais également l'action de la règle. Pourtant, j'utilise la clause INSTEAD : d'après la doc, si la règle se déclenche, l'action s'exécute A LA PLACE de la requête. Au pire, je comprendrais que l'insert ne fonctionne plus et que la règle se déclenche, mais l'insert ET la règle ....

Je suis en PostgreSQL 8.3.8

Voici un exemple simplifié de mon pb :

table principale : create table test (cle_test varchar(2),libelle_test varchar(20) );
clé unique :alter table only test add constraint pk_test primary key (cle_test);
table d'anomalie : create table erreur (libelle_erreur varchar(20) );

la règle : si une ligne existe déjà dans TEST avec la même valeur de CLE_TEST, on remplace l'insert (qui aurait fait planter en index dupliqué) par une écriture dans la table d'anomalie
create or replace rule "ins_test" as
on insert to test where exists (
    select    cle_test
    from    test
    where    test.cle_test    = new.cle_test    )
do instead
    insert into erreur values ('code ' ||new.cle_test||' existe déjà') ;

première insertion :
insert into test values ('01', 'un essai');

select * from test;
01    un essai

select * from erreur;
code 01 existe déjà    POURQUOI ???

deuxième insertion
insert into test values ('01', 'un essai');

select * from test;
01    un essai

select * from erreur;
code 01 existe déjà
code 01 existe déjà   c'est normal

Merci d'avance pour votre aide.

Hors ligne

#2 12/02/2010 08:16:13

Marc Cousin
Membre

Re : Problème avec une règle en INSERT

D'après la doc : http://docs.postgresql.fr/8.4/rules-update.html
Pour les règles on insert, la requête originale (si elle n'est pas supprimée par instead) est réalisée avant toute action ajoutée par les règles.

Je pense donc que ton problème provient du fait que l'insert a déjà été effectué avant le test exist…

Par contre j'utilise peu les règles, peut être quelqu'un d'autre aura un contournement à proposer…


Marc.

Hors ligne

#3 12/02/2010 09:38:07

gleu
Administrateur

Re : Problème avec une règle en INSERT

La seule solution de contournement que je vois est le trigger, bien plus simple à débogguer.


Guillaume.

Hors ligne

#4 12/02/2010 10:54:16

Patrick Sch
Membre

Re : Problème avec une règle en INSERT

Merci pour vos réponses rapides.

C'est dommage que la règle ne réagisse pas comme la doc l'indique. Mais bon ...

J'ai regardé le principe des triggers, effectivement je dois pouvoir obtenir ce que je veux. Reste à voir la syntaxe.

Cordialement.

Hors ligne

Pied de page des forums