|
Publicité ' | |||||||||||||||||||||||
|
|
#1 |
|
Invité régulier
![]() Inscription : septembre 2007 Messages : 3 ![]() |
Nous tentons d'appliquer une integrité referentiel entre deux tables (CNT et CNU).
un enregistrement CNU(contrat unitaire) peut etre inserer si l'on trouve son contrat (CNT). pour cela, nous utilisons un trigger. il est declarer de la sorte et appliquer sur la table cible (CNU): CREATE OR REPLACE TRIGGER CNU_CONTROLE_CNT BEFORE INSERT ON CNU_CONTRAT_UNITAIRE REFERENCING NEW AS NEW OLD AS OLD FOR EACH ROW DECLARE trouver NUMBER:=0 ; BEGIN -- vérifivation de la présence du contrat actif SELECT COUNT(*) INTO trouver FROM CNT_CONTRAT a WHERE :new.CNT_CODE = a.CNT_CODE AND :new.CNU_INV_DEB >= a.CNT_INV_DEB and :new.CNU_INV_DEB < a.CNT_INV_FIN ; IF trouver <> 0 THEN RAISE_APPLICATION_ERROR(-00001,'NAME: Pas de contrat valide dans la table CNT_CONTRAT //END'); END IF; END CNU_CONTROLE_CNT; / Nous nous attendons donc a recuperer les enregistrement rejetés par le trigger (on attend un fonctionnement identique a un rejet sur une PK/FK). Cependant, le programme effectuant les insert passe en Failed dès qu'on 'tombe' sur un enregistrement ne respectant pas le trigger. le message d'erreur envoyé est le suivant: Severity Timestamp Node Thread Message Code Message ERROR 11/09/2007 17:31:07 node01_rs39 WRITER_1_*_1 WRT_8229 Database errors occurred: ORA-20011: NAME: Pas de contrat valide dans la table CNT_CONTRAT //END ORA-06512: à "XOB.CNU_CONTROLE_CNT", ligne 14 ORA-04088: erreur lors d'exécution du déclencheur 'XOB.CNU_CONTROLE_CNT' Comment peut on contourner le 'Failed' et recuperer les rejets associés au trigger? |
|
|
10
|
|
|
#2 |
|
Expert Confirmé Sénior
![]() ![]() ![]() Laurent SchneiderAdministrateur de base de données Inscription : décembre 2005 Messages : 2 927 ![]() |
pourquoi réinventé la roue?
Oracle a des contraintes d'inégrités référentielles bien plus efficaces qu'un trigger maison. Quant à récupérer les enregistrements rejettés, il suffit de faire Code :
INSERT INTO t VALUES (blabla) log errors ; |
|
00
|
|
|
#3 |
|
Invité régulier
![]() Inscription : septembre 2007 Messages : 3 ![]() |
Il est vrai qu'il est inutile de reinventer la roue!
le souci qui se pose est que l'on utilise un ETL, Informatica Powercenter pour charger dans les tables nos enregistrements. Ainsi, quand oracle rejete un enregistrement pour contrainte d'integrité ou autre, nous avons le moyen de les recuperer. Nous souhaitons alors appliquer une nouvelle contrainte referentiel (lié a une table 'mère'->un CNU ne peut etre inserer si le CNT n'existe pas). L'idée est alors de laisser oracle géré le rejet lié a cette contrainte. nous pensions qu'il rejeterait l'enregistrement 'normalement' (comme il peut le fait sur une contrainte d'integrité). l'usage du trigger nous semble plus 'confortable' car ce type de contrainte d'integrité est a appliquer sur d'autres tables (suivant le meme principe: une table mère/une table fille, on insert dans la fille uniquement si on trouve la clé dans la mere). Comment peut on lever un warning dans un trigger? ce pourrait etre la solution... dans notre trigger on leve un erreur qui fait 'planter' l'application RAISE_APPLICATION_ERROR. Si on utilise un 'raise_warning' l'application continuerait probablement son travail... la version d'oracle utilisé est la 10g |
|
|
10
|
|
|
#4 |
|
Expert Confirmé Sénior
![]() ![]() ![]() Laurent SchneiderAdministrateur de base de données Inscription : décembre 2005 Messages : 2 927 ![]() |
je n'aime pas trop les triggers, c'est moins fiable que les contraintes.
|
|
00
|
|
|
#5 |
|
Invité régulier
![]() Inscription : septembre 2007 Messages : 3 ![]() |
Exact, les contraintes c'est meilleur!!!
la ruse est de modifier l'enregistrement a inserer pour qu'il soit rejeté par une contrainte existante(on ne peut pas ajouter de contrainte sur les tables). Ainsi, nous avons un champ (que l'on renseigne toujours) qui doit etre non null. nous nous servons de cette contrainte pour effectuer notre rejet dans notre trigger. il suffit de mettre a null le champ lorque l'on tente d'inserer un enregistrement n'ayant pas de contrat CNU. voici le code CREATE OR REPLACE TRIGGER CNU_CONTROLE_CNT BEFORE INSERT ON CNU_CONTRAT_UNITAIRE REFERENCING NEW AS NEW OLD AS OLD FOR EACH ROW DECLARE trouver NUMBER:=0 ; BEGIN -- vérifivation de la présence du contrat actif SELECT COUNT(*) INTO trouver FROM CNT_CONTRAT a WHERE :new.CNT_CODE = a.CNT_CODE AND :new.CNU_INV_DEB >= a.CNT_INV_DEB and :new.CNU_INV_DEB < a.CNT_INV_FIN ; IF trouver=0 THEN :new.CNU_INV_FIN := NULL; END IF; END CNU_CONTROLE_CNT; / Merci pour ton aide...ca m'a mis sur la bonne piste! |
|
|
10
|
Copyright © 2000-2012 - www.developpez.com