#1 Fri 30 January 2009 11:47
- NyPon
- Participant actif
- Date d'inscription: 3 Nov 2008
- Messages: 111
Déclencheur héritage
Bonjour,
j'essaye de gérer l'héritage dans PostGIS par la mise en place d'un déclencheur, mais je n'y arrive pas.
j'utilise Postgresql 8.3.5,
j'ai une table acquisition :
Code:
CREATE TABLE acquisition ( id_acquisition serial NOT NULL, numero character varying(16) NOT NULL, proprio character varying(30) NOT NULL, libre boolean, exploitant character varying(30), CONSTRAINT cle_acqui PRIMARY KEY (id_acquisition), CONSTRAINT fk_opef FOREIGN KEY (numero) REFERENCES operation (prodcom) MATCH SIMPLE ON UPDATE NO ACTION ON DELETE NO ACTION, CONSTRAINT acq_prodcom_check CHECK (numero::text ~~ 'A%'::text) ) WITH (OIDS=TRUE); ALTER TABLE acquisition OWNER TO postgres;
et j'ai une table opération
Code:
CREATE TABLE operation ( id_operation integer NOT NULL DEFAULT nextval('opef_id_opef_seq'::regclass), numero character varying(16), date date DEFAULT ('now'::text)::date, CONSTRAINT cle_opef PRIMARY KEY (id_operation), CONSTRAINT prod_unique UNIQUE (numero) ) WITH (OIDS=FALSE); ALTER TABLE operation OWNER TO postgres;
Une acquisition est un type d'opération, d'où la notion d'héritage.
par la suite, j'aurais aussi des locations... qui seront d'autre types d'opérations.
je voudrais faire un déclencheur pour chaque insertion dans la table "acquisition" afin qu'il récupère le numéro et qu'il l'intègre dans la table "opération".
mais j'ai plusieurs problèmes :
la clé étrangère faisant référence à la table opération m'empêche de faire l'insertion dans "acquisition" car lorsque je veux intégrer il me dit que la référence n'existe pas.
j'ai fait un déclencheur, surement incomplet :
Code:
CREATE OR REPLACE FUNCTION insert_operation() RETURNS "trigger" AS $BODY$ DECLARE -- Declare les variables. oper character varying(16); BEGIN SELECT INTO oper numero FROM acquisition WHERE numero = NEW.numero; IF TG_OP = 'INSERT' AND FOUND THEN UPDATE operation SET numero= NEW.numero WHERE numero = NEW.numero; END IF; RETURN NEW; END; $BODY$ LANGUAGE 'plpgsql' VOLATILE; ALTER FUNCTION insert_operation() OWNER TO postgres; CREATE TRIGGER trig_insert_acquisition AFTER INSERT OR UPDATE ON acquisition FOR EACH ROW EXECUTE PROCEDURE insert_operation();
D'une part, je ne suis pas sure que mon trigger fonctionne bien malgré le fait que postgres réalise la requête avec succès.
D'autre part, j'imagine qu'il faille ajouter une condition "BEFORE" avant d'insérer dans la table opération pour intégrer les données issues d'acquisition.
Voilà, je ne sais pas si je suis clair ?
merci d'avance, à bientôt,
cordialement,
Hors ligne
#2 Fri 30 January 2009 22:29
- cedricd
- Participant occasionnel
- Lieu: Dijon
- Date d'inscription: 20 Mar 2006
- Messages: 19
Re: Déclencheur héritage
Bonsoir,
Posgresql propose des fonctions d'héritage de table(instruction INHERITS dans le CREATE TABLE) qui peuvent peut- être vous aider.
En me basant sur votre exemple et en ajoutant une table "location" cela pourrait donner :
Code:
CREATE TABLE operation ( id_operation serial NOT NULL, numero character varying(16), date date DEFAULT ('now'::text)::date, CONSTRAINT cle_opef PRIMARY KEY (id_operation), CONSTRAINT prod_unique UNIQUE (numero) ); CREATE TABLE acquisition ( proprio character varying(30) NOT NULL, libre boolean, exploitant character varying(30) ) INHERITS (operation); CREATE TABLE location ( colonne1 character varying(30), colonne2 character varying(30) ) INHERITS (operation); INSERT INTO acquisition (numero,proprio,libre,exploitant) VALUES('A1','PROPRIO 1',FALSE,'EXPLOITANT 1'); INSERT INTO acquisition (numero,proprio,libre,exploitant) VALUES('A2','PROPRIO 2',TRUE,'EXPLOITANT 2'); INSERT INTO acquisition (numero,proprio,libre,exploitant) VALUES('A3','PROPRIO 3',FALSE,'EXPLOITANT 3'); INSERT INTO location (numero,colonne1,colonne2) VALUES('L1','A','AA'); INSERT INTO location (numero,colonne1,colonne2) VALUES('L2','B','BB');
On a donc 3 acquisitions, 2 locations, et un total de 5 opérations
En espérant que cela réponde à votre attente.
Cordialement.
Hors ligne
#3 Mon 02 February 2009 09:23
- NyPon
- Participant actif
- Date d'inscription: 3 Nov 2008
- Messages: 111
Re: Déclencheur héritage
Bonjour Cedricd,
merci pour la réponse
J'avais procédé de telle manière mais il s'avère que dans ma table exploitation, les données sont "fictives". en effet, cette table "opération" à une relation n,n avec une table "parcelle", lorsque je souhaite insérer des données dans la table d'association "operation_parcelle", j'ai un message d'erreur me disant que mes données sont inexistantes dans la table "opération". Or elles existent bien lorsque je les consultes.
Je n'ai cependant pas la même syntaxe :
Code:
CREATE TABLE acquisition ( -- Hérité(e): id_operation integer NOT NULL DEFAULT nextval('opef_id_opef_seq'::regclass), -- Hérité(e): numero character varying(16), -- Hérité(e): date date , proprio character varying(30) NOT NULL, libre boolean, exploitant character varying(30), CONSTRAINT cle_acq PRIMARY KEY (id_operation), CONSTRAINT acq_check CHECK (numero::text ~~ 'A%'::text) ) INHERITS (operation) WITH (OIDS=FALSE); ALTER TABLE acquisition OWNER TO postgres;
on m'avait parlé de ce problème et on m'a conseillé d'utiliser des déclencheurs pour éviter se problème et avoir des données "en dur" dans la table opération.
je contourne le problème en ayant un numéro unique que je contrôle dans "operation" et "operation_parcelle".
cependant il me semble que cette solution ne soit pas très robuste ?
c'est pour cette raison que je souhaite maintenant gérer l'héritage avec des déclencheurs.
si vous avez des pistes, je suis preneur.
merci encore,
cordialement,
Nicolas,
Hors ligne
#4 Mon 02 February 2009 11:30
- NyPon
- Participant actif
- Date d'inscription: 3 Nov 2008
- Messages: 111
Re: Déclencheur héritage
Bonjour,
Pour info, voici un exemple :
http://geekblog.over-blog.com/article-17775481.html
à bientôt, cordialement,
nicolas
Hors ligne
#5 Mon 02 February 2009 11:58
Re: Déclencheur héritage
Bonjour,
Si tu veux effectuer un héritage dans le sens "objet", tu n'as pas besoin de
passer par des déclencheurs. En fait Postgres comprend une notion d'héritage
de table.
En SQL, c'est quelque chose du genre :
CREATE TABLE ta_table_fille
(
-- Hérité(e): srid integer NOT NULL,
-- Hérité(e): auth_name character varying(256),
-- Hérité(e): auth_srid integer,
-- Hérité(e): srtext character varying(2048),
-- Hérité(e): proj4text character varying(2048)
)
INHERITS (ta_table_mere)
Avec cette méthode, quand tu enregistres tes données dans la table fille,
les champs commune de la table mère seront automatiquement saisie.
C'est, d'après ce que j'ai compris de ton problème, la meilleurs méthode...
Tu as une table operation (mère) avec autant de table fille que de catégorie
d'opération.
Cordialement
Hors ligne
#6 Mon 02 February 2009 13:50
- NyPon
- Participant actif
- Date d'inscription: 3 Nov 2008
- Messages: 111
Re: Déclencheur héritage
Bonjour cbredel,
En effet, c'est mon problème.
mais c'est un peu plus complexe que ça :
lorsque je saisi une nouvelle entrée dans la table fille (acquisition), l'enregistrement, se retrouve bien dans la table mère (opération).
là où ça se complique, c'est lorsqu'on veut faire un lien de n à n avec une autre table si on essaye de remplir la table d'association avec l'identifiant de la table opération, j'ai une erreur du style : " l'identifiant n'existe pas dans la table opération".
n'avez-vous pas ce genre de problème ?
en tout cas, merci pour les réponses,
cordialement,
Nicolas.
Hors ligne
#7 Mon 02 February 2009 22:42
- ChristopheV
- Membre
- Lieu: Ajaccio
- Date d'inscription: 7 Sep 2005
- Messages: 3199
- Site web
Re: Déclencheur héritage
Bonjour,
Sans entrer sous Postgis que je ne connais pas assez pour entrer dans ces notions complexes, je vous propose la définition de l'héritage objet pour SQL tel que défini par P.A. Muller et N. Gaertner dans la "modélisation objet avec UML". l'objet B hérite de l'objet A
Héritage simple: Chaque classe est réalisée par une table. L'identité d'un objet est préservée dans la hiérarchie de classe par l'emploi d'un identifiant partagé
Code:
CREATE TABLE T_A( A_Id NUMBER (5) PRIMARY KEY (A_Id) ) CREATE TABLE T_B( A_Id NUMBER(5) REFERENCES T_A (A_Id), PRIMARY KEY (A_Id) )
Si cela peut aider (nb je ne trouve pas le mot clef "REFERENCES" dans SQL ....)
Christophe
L'avantage d'être une île c'est d'être une terre topologiquement close
Hors ligne