Vous n'êtes pas identifié(e).
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
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. :-)
damien clochard
http://dalibo.org | http://dalibo.com
Hors ligne
Merci.
Nous sommes dans un contexte applicatif particulier qui justifie ce fonctionnement.
Je regarde votre lien.
encore merci.
Hors ligne
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