PostgreSQL
La base de données la plus sophistiquée au monde.

Ouverture de session

Navigation

Contactez-nous

Administration du site :
"equipe chez postgresqlfr point org"

Contact presse :
"fr chez postgresql point org"

Contact association :
"bureau chez postgresqlfr point org"

Questions PostgreSQL :
 IRC :
  serveur irc.freenode.net
  canal #postgresqlfr

Recherche

Accéder aux archives

« Octobre 2008  
Lun Mar Mer Jeu Ven Sam Dim
  2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31  

Syndication

Flux XML

Sondage

Quelle est la version de PostgreSQL la plus répandue sur vos serveurs ?
8.3
10%
8.2
42%
8.1
40%
8.0
2%
7.4
6%
7.3 ou antérieure
0%
Nombre de votes: 48

Partitionnement de table et clef serial

Technique - général | Partitionnement de table et clef serial

Par rupteur le 14/08/2008 - 16:29

Bonjour,

je suis actuellement en train de tester le partitionnement de table,
et je me retrouve confronté à un problème de contrainte de clef étrangère

j'ai défini 4 table filles qui héritent d'une table mère (reference_test).
j'ai posé un trigger qui défini où doivent être insérées/modifiées/effacées les données.
j'ai aussi une table résultat qui possède une clef primaire étrangère (celle de la table mère)

lorsque j'insère les données dans la table mère, celles-ci sont bien diffusées où il faut.
INSERT INTO reference_test (clef_etr1,clef_etr2,clef_etr3,clef_etr4,ref_datetest,ref_pos1,ref_pos2,anadef_clef,typana_clef) VALUES (1,0,0,0,NOW(),50,1,1,1);
INSERT INTO reference_test (clef_etr1,clef_etr2,clef_etr3,clef_etr4,ref_datetest,ref_pos1,ref_pos2,anadef_clef,typana_clef) VALUES (0,1,0,0,NOW(),100,25,1,1);

mais si je tente une insertion dans la table resultat,
INSERT INTO resultat(ref_clef,res_plaque) VALUES(2,1);

j'obtient le message d'erreur suivant :

ERREUR: Une instruction insert ou update sur la table « resultat » viole la contrainte de clé étrangère « ref1 »
DETAIL: La clé (ref_clef)=(2) n'est pas présente dans la table « reference_test ».

Peut-être que je ne gère pas le partitionnement comme il le faudrait.

Merci d'avance pour vos éclaircissements.

Eric

ci-joint mon code pour plus de clarté.

CREATE TABLE reference_test
(
ref_clef bigserial NOT NULL,
clef_etr1 bigint,
clef_etr2 bigint,
clef_etr3 bigint,
clef_etr4 bigint,
ref_datetest date NOT NULL,
ref_pos1 numeric(4) NOT NULL,
ref_pos2 numeric(2) NOT NULL,
anadef_clef integer NOT NULL,
typana_clef integer NOT NULL,
PRIMARY KEY (ref_clef)
);

CREATE TABLE resultat
(
ref_clef bigint NOT NULL,
res_plaque numeric(4) DEFAULT 0 NOT NULL,
PRIMARY KEY (ref_clef)
);

ALTER TABLE resultat ADD CONSTRAINT ref1
FOREIGN KEY ( ref_clef )
REFERENCES reference_test ( ref_clef )
NOT DEFERRABLE;

CREATE TABLE reftest_cl
( CHECK (clef_etr1 IS NOT NULL AND clef_etr1>0::bigint))
INHERITS (reference_test);

CREATE TABLE reftest_ip
( CHECK (clef_etr2 IS NOT NULL AND clef_etr2>0::bigint))
INHERITS (reference_test);

CREATE TABLE reftest_cit
( CHECK (clef_etr3 IS NOT NULL AND clef_etr3>0::bigint))
INHERITS (reference_test);

CREATE TABLE reftest_div
( CHECK (clef_etr4 IS NOT NULL AND clef_etr4>0::bigint))
INHERITS (reference_test);

CREATE FUNCTION reference_test_handler()
RETURNS TRIGGER AS $$
DECLARE
BEGIN
IF tg_op = 'INSERT' THEN
IF new.clef_etr1 IS NOT NULL AND new.clef_etr1>0 THEN
INSERT INTO reftest_cl
(clef_etr1,clef_etr2,clef_etr3,clef_etr4,ref_datetest,ref_pos1,ref_pos2,anadef_clef,typana_clef)
VALUES (new.clef_etr1,new.clef_etr2,new.clef_etr3,new.clef_etr4,new.ref_datetest,new.ref_pos1,
new.ref_pos2,new.anadef_clef,new.typana_clef);
ELSIF new.clef_etr2 IS NOT NULL AND new.clef_etr2>0 THEN
INSERT INTO reftest_ip
(clef_etr1,clef_etr2,clef_etr3,clef_etr4,ref_datetest,ref_pos1,ref_pos2,anadef_clef,typana_clef)
VALUES (new.clef_etr1,new.clef_etr2,new.clef_etr3,new.clef_etr4,new.ref_datetest,new.ref_pos1,
new.ref_pos2,new.anadef_clef,new.typana_clef);
ELSIF new.clef_etr3 IS NOT NULL AND new.clef_etr3>0 THEN
INSERT INTO reftest_cit
(clef_etr1,clef_etr2,clef_etr3,clef_etr4,ref_datetest,ref_pos1,ref_pos2,anadef_clef,typana_clef)
VALUES (new.clef_etr1,new.clef_etr2,new.clef_etr3,new.clef_etr4,new.ref_datetest,new.ref_pos1,
new.ref_pos2,new.anadef_clef,new.typana_clef);
ELSIF new.clef_etr4 IS NOT NULL AND new.clef_etr4>0 THEN
INSERT INTO reftest_div
(clef_etr1,clef_etr2,clef_etr3,clef_etr4,ref_datetest,ref_pos1,ref_pos2,anadef_clef,typana_clef)
VALUES (new.clef_etr1,new.clef_etr2,new.clef_etr3,new.clef_etr4,new.ref_datetest,new.ref_pos1,
new.ref_pos2,new.anadef_clef,new.typana_clef);
END IF;
END IF;
IF tg_op = 'UPDATE' THEN
IF old.clef_etr1 IS NOT NULL AND old.clef_etr1>0 THEN
UPDATE reftest_cl SET clef_etr1=new.clef_etr1,clef_etr2=new.clef_etr2_clef,clef_etr3=new.clef_etr3,
clef_etr4=new.clef_etr4,ref_datetest=new.ref_datetest,ref_pos1=new.ref_pos1,
ref_pos2=new.ref_pos2,anadef_clef=new.anadef_clef,typana_clef=new.typana_clef;
ELSEIF old.clef_etr2 IS NOT NULL AND old.clef_etr2>0 THEN
UPDATE reftest_ip SET clef_etr1=new.clef_etr1,clef_etr2=new.clef_etr2_clef,clef_etr3=new.clef_etr3,
clef_etr4=new.clef_etr4,ref_datetest=new.ref_datetest,ref_pos1=new.ref_pos1,
ref_pos2=new.ref_pos2,anadef_clef=new.anadef_clef,typana_clef=new.typana_clef;
ELSEIF old.clef_etr3 IS NOT NULL AND old.clef_etr3>0 THEN
UPDATE reftest_cit SET clef_etr1=new.clef_etr1,clef_etr2=new.clef_etr2_clef,clef_etr3=new.clef_etr3,
clef_etr4=new.clef_etr4,ref_datetest=new.ref_datetest,ref_pos1=new.ref_pos1,
ref_pos2=new.ref_pos2,anadef_clef=new.anadef_clef,typana_clef=new.typana_clef;
ELSEIF old.clef_etr4 IS NOT NULL AND old.clef_etr4>0 THEN
UPDATE reftest_div SET clef_etr1=new.clef_etr1,clef_etr2=new.clef_etr2_clef,clef_etr3=new.clef_etr3,
clef_etr4=new.clef_etr4,ref_datetest=new.ref_datetest,ref_pos1=new.ref_pos1,
ref_pos2=new.ref_pos2,anadef_clef=new.anadef_clef,typana_clef=new.typana_clef;
END IF;
END IF;
IF tg_op = 'DELETE' THEN
IF old.clef_etr1 IS NOT NULL AND old.clef_etr1>0 THEN
DELETE FROM reftest_cl;
ELSEIF old.clef_etr2 IS NOT NULL AND old.clef_etr2>0 THEN
DELETE FROM reftest_ip;
ELSEIF old.clef_etr3 IS NOT NULL AND old.clef_etr3>0 THEN
DELETE FROM reftest_cit;
ELSEIF old.clef_etr4 IS NOT NULL AND old.clef_etr4>0 THEN
DELETE FROM reftest_div;
END IF;
END IF;
RETURN NULL;
END;
$$ LANGUAGE plpgsql;

CREATE TRIGGER reference_test_handler_trg
BEFORE INSERT OR UPDATE OR DELETE
ON reference_test
FOR EACH ROW
EXECUTE PROCEDURE reference_test_handler();

Options d'affichage des commentaires

Sélectionnez la méthode d'affichage des commentaires que vous préférez, puis cliquez sur "Sauvegarder les paramètres" pour activer vos changements.

Bon, il semblerait que ce soi

rupteur/ = 18 Août, 2008 - 09:09

Bon, il semblerait que ce soit une "limitation" de postgresql.

les contraintes des clefs étrangères ne sont vérifiées qu'au niveau de la table mère, pas aux tables filles.


© PostgreSQLFr, tous droits réservés.
Site déclaré à la CNIL sous le numéro 1074678, conformément à la Loi en vigueur.