2008-12-17 14 views
0

J'ai analysé une base de données Oracle générée par hibernate et j'ai découvert qu'une suppression d'une ligne d'une seule table déclencherait le déclenchement de plus de 1200 déclencheurs afin de supprimer les lignes associées dans les tables enfants. Les déclencheurs sont tous générés automatiquement de la même manière - une suppression automatique d'une ligne enfant sans vérifier l'existence en premier. Comme il est impossible de prédire quelles tables enfants auront réellement des lignes liées, je pense qu'une solution viable pour empêcher le déclenchement de la suppression en cascade d'un membre complètement vide complètement ramifié, serait de vérifier l'existence d'une ligne liée avant de tenter de effacer. Dans d'autres dbms, je pourrais simplement dire "si existe ..." avant de supprimer. Existe-t-il une façon comparable de le faire en oracle?Oracle vérifiant l'existence avant la suppression dans un déclencheur

+0

Qu'entendez-vous par 1200+ Trigger? y a-t-il 1200 objets déclencheurs? ou il y a 1200 appels déclencheurs? – Salamander2007

Répondre

0

Vous pouvez interroger la table dba_objects spéciales:

DECLARE 
X NUMBER; 
BEGIN 
    SELECT COUNT(*) INTO X FROM DBA_OBJECTS WHERE OBJECT_TYPE = 'TRIGGER' AND OBJECT_NAME = 'YOUR_TRIGGER_NAME_HERE'; 
    IF X = 0 THEN 
     --Trigger doesn't exist, OK to delete... 
    END IF; 
END; 
+1

Désolé. Apparemment, je n'étais pas clair. Je ne souhaite pas vérifier l'existence du déclencheur lui-même. Je souhaite vérifier l'existence de données dans la table enfant supprimée par le déclencheur du parent. –

2

Si possible, modifier et configurer vos tables de DB de façon appropriée. - Impliquez un DBA si vous en avez un à votre disposition. Vous devez utiliser Foreign Key constraints and cascade deletes. Cela élimine le besoin de déclencheurs, etc ...

4

"La suppression d'une ligne d'une seule table provoque le déclenchement de plus de 1200 déclenchements" Ces déclencheurs d'instructions ou de lignes sont-ils déclenchés? Si ce dernier, ils se déclencheront uniquement si une ligne est supprimée. Supposons que vous ayez un déclencheur BEFORE DELETE sur les clients pour supprimer les commandes des clients et un déclencheur BEFORE DELETE sur les commandes pour supprimer les articles de la commande. Si le client n'a aucune commande et que le déclencheur de la table des commandes est un déclencheur de niveau ligne, il ne déclenchera pas la suppression des articles de la commande. "Vérifier l'existence d'une ligne liée avant d'essayer de supprimer" Probablement aucun avantage. En fait, il ferait plus de travail ayant un SELECT suivi d'un DELETE.

Bien sûr, la logique Hibernate est cassée. La session de suppression verra seulement (et essayera de supprimer) les transactions validées. Si FRED a inséré une commande pour le client, mais qu'elle n'est pas validée, la suppression de JOHN (via le déclencheur) ne la verra pas et n'essaiera pas de la supprimer. Il va cependant toujours réussir et tenter de supprimer le client parent. Si vous avez activé vos contraintes de clé étrangère dans la base de données, Oracle entrera en jeu. Il attendra que FRED valide, puis rejettera la suppression car il a un enfant. Si les contraintes de clé étrangère ne sont pas en place, vous avez une commande pour un client inexistant. C'est pourquoi vous devriez avoir ce type de logique métier appliquée dans la base de données.

0
select * from Tab where Tname = "TABLENAME" 

Si cette requête renvoie une ligne, la table existe sinon elle ne l'est pas.