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 04/07/2011 14:54:14

cbeau
Membre

Substituer dans trigger, INSERT par UPDATE, si clé déjà existante

Bonjour.

Comment remplacer  dans un trigger, l’exécution INSERT par UPDATE après avoir contrôlé que le champ contenant la clé, existe déjà dans la table concernée par l’Insert (pour traitement de tables héritées où le contrôle d’unicité de la clé n’est pas possible nativement).

Merci.

Mon ébauche :
CREATE OR REPLACE FUNCTION f_ctrl_doublons() RETURNS TRIGGER AS $t_ctrl_doublons$
BEGIN
IF (TG_OP = 'INSERT') THEN
  IF (SELECT count(*) FROM table WHERE cléinsérée = cléexistante) <> NULL;
       Provoquer ici le remplacement l’Insert par un Update
    END IF;
  END IF;
END;

CREATE TRIGGER t_ctrl_doublons BEFORE INSERT ON “table”
FOR EACH ROW ?

Hors ligne

#2 04/07/2011 17:04:38

daamien
damien clochard

Re : Substituer dans trigger, INSERT par UPDATE, si clé déjà existante

Attention : agir de la sorte signifie que vous allez "tromper" l'application et les utilisateurs. Ainsi un utilisateur de la base lancera un INSERT, qui sera remplacé à la volée par une UPDATE sans que celui-ci en soit informé. C'est pas très propre et ça peut conduire à de très grosses incompréhensions.

D'un point de vue logique, c'est plutot l'application qui doit "prendre la décision" de faire un INSERT ou un UPDATE.... Par exemple, le fait que l'appli tenter d'insérer un ligne qui est déjà dans la base c'est une information en soit et ce n'est pas la même chose qu'une mise à jour d'une ligne. Pourtant avec ce que vous proposer, les deux opérations auront le même résultat.

Par ailleurs, une fonction telle que vous l'écrivez ci-dessus aura un impact négatif sur vos perf en écriture.

Malgré tout, si vous voulez vraiment faire ce genre de ré-écriture à la volée alors les règles (RULES) sont faites pour vous :

http://docs.postgresql.fr/9.1/rules-privileges.html

Mais au risque d'être lourd, j'insiste une dernière fois : les subsitutions de requêtes à la volée sont un moyen simple et rapide de faire n'importe quoi avec vos données. :-)

Hors ligne

#3 04/07/2011 17:27:51

cbeau
Membre

Re : Substituer dans trigger, INSERT par UPDATE, si clé déjà existante

Merci.

Nous sommes dans un contexte applicatif particulier qui justifie ce fonctionnement.

Je regarde votre lien.

encore merci.

Hors ligne

#4 04/07/2011 19:01:41

cedric
Membre

Re : Substituer dans trigger, INSERT par UPDATE, si clé déjà existante

Le comportement des 'rules' sur des tables non-vides (cad en-dehors de l'utilisation classique sur une vue ou une table 'mère') peut lui-même conduire à des situations assez innatendues pour le DBA, mais parfaitement cohérentes pour le moteur de réécriture. Je déconseille fortement. cf sur le sujet http://blog.rhodiumtoad.org.uk/2010/06/ … challenge/
Il y aussi quelques exemples qui trainent sur le net avec des cas précis où le comportement quoique normal est surprenant si vous voulez creuser.

Ce que vous cherchez à faire ressemble fort à un 'UPSERT'.
cf http://www.postgresql.org/docs/current/ … R-TRAPPING example 39-2

On préfère donc implémenter cela au niveau de l'appli par un appel spécifique au lieu de INSERT/UPDATE. Vous pouvez vous en inspirer pour faire votre trigger... Attention à bien prendre en compte la concurrence d'accès à vos données.


Cédric Villemain +33 (0)6 20 30 22 52
http://2ndQuadrant.fr/
PostgreSQL: Support 24x7 - Développement, Expertise et Formation

Hors ligne

Pied de page des forums