2010-06-30 12 views
1

J'ai une structure hiérarchique stockée dans une table. Chaque élément a un pointeur vers le précédent, à côté et un parentUtilisation de déclencheurs pour assurer la cohérence des données

create table CATALOGUE 
(
    NAME VARCHAR2(300) not null, 
    NEXT_ID NUMBER(38), 
    PARENT_ID NUMBER(38), 
    PREVIOUS_ID NUMBER(38), 
    XID NUMBER(38) 
); 

j'ai une application Java, qui utilise le mappage O/R pour accéder et modifier ce tableau. Parfois, mon catalogue est corrompu, par ex. ce sont des éléments liés qui n'ont pas le même parent. Je me demande si je peux assurer la cohérence des données en utilisant des déclencheurs Oracle ou une autre technique SQL pure (sans code Java).

Est-ce "la bonne façon" de faire les choses?

Comment puis-je implémenter un trigger? Je peux implémenter une procédure stockée qui validerait ma table. Quelque chose comme

select count(*) 
from catalogue c1, catalogue c2 
where c1.next_id = c2.previous_id and c1.parent_id != c2.parent_id 

doit retourner 0.

Mais comment puis-je l'appeler lors de la validation? Je ne veux pas l'appeler à chaque mise à jour de ligne, juste avant que la validation ne soit terminée avec une possibilité de restauration si ma table n'est pas valide.

+0

"ce sont des éléments liés qui n'ont pas le même parent" Comment un déclencheur pourrait-il jamais déterminer ce que le "même parent" pourrait signifier? –

+0

@ S.Lott: J'ai ajouté quelques informations pour être plus clair. –

Répondre

2

Il peut être possible d'appliquer ceci par une combinaison d'une vue matérialisée (MV) et d'une contrainte sur le MV comme je l'ai décrit here in my blog.

L'idée serait de créer un MV qui ne contiendrait que des exceptions à la règle, puis d'avoir une contrainte qui échoue toujours lorsqu'une ligne est entrée dans le MV. Quelque chose comme ceci:

create materialized view check_mv 
refresh complete on commit as 
select 1 dummy 
from catalogue c1, catalogue c2 
where c1.next_id = c2.previous_id and c1.parent_id != c2.parent_id 

alter table check_mv 
add constraint check_mv_chk 
check (1=0) deferrable; 
+0

Tony, merci beaucoup. –

1

Idéalement, vous devriez écrire un paquet qui contrôle à 100% la maintenance de cette table. Si nécessaire, placez-le dans son propre schéma, verrouillez les privilèges sur celui-ci et utilisez UNIQUEMENT CE PAQUET pour modifier la table.

+0

Merci pour votre réponse. Comme je l'ai déjà expliqué, j'ai une application Java. Plus précisément, une application buggy java. Je veux utiliser du SQL pur pour éviter les incohérences dans la base de données. Mais je ne veux pas passer de l'implémentation de ma logique métier de java à SQL. –

+0

Je voudrais offrir le même conseil, juste sous forme java - avoir une classe Java qui gère la maintenance de cette table. Il est plus difficile de l'utiliser, mais pour quelque chose d'aussi important, vous avez besoin d'un contrôle centralisé. Sinon, vous allez chasser les insectes à perpétuité. Je ne sais pas quel est votre niveau d'activité dans l'application, mais d'autres solutions entraîneront des frais supplémentaires. Bonne chance, et +1 pour une question intéressante ... – DCookie