2014-06-11 1 views
1

Hey j'ai eu un petit problème avec la création d'un trigger sur ma base de données.ORACLE Trigger Check Table et supprimer la ligne

J'ai une table qui porte le nom 'situé' et contient:

  • Pays
  • Ville
  • Province
  • Lac
  • Sea
  • rivière

Alors Lac , La mer et la rivière sont des clés étrangères.

J'ai créé ces trois contraintes:

ALTER TABLE located 
ADD CONSTRAINT locatedLake 
     FOREIGN KEY (lake) 
     REFERENCES Lake(name) 
     ON DELETE SET NULL; 

ALTER TABLE located 
ADD CONSTRAINT locatedRiver 
     FOREIGN KEY (river) 
     REFERENCES River(name) 
     ON DELETE SET NULL; 

ALTER TABLE located 
ADD CONSTRAINT locatedSea 
     FOREIGN KEY (sea) 
     REFERENCES Sea(name) 
     ON DELETE SET NULL; 

Ainsi, chaque fois que je supprimer un lac, une rivière ou mer il est situé à NULL.

Maintenant, j'essayé de créer ce déclencheur:

CREATE OR REPLACE TRIGGER deleteFromLocated 
AFTER UPDATE ON located 
FOR EACH ROW 
BEGIN 
     DROP FROM located WHERE sea IS NULL AND river IS NULL AND lake IS NULL; 
END; 
/

Mais je reçois une erreur mutationniste.

Le but est de supprimer tous les tuples où ces trois choses sont nulles.

Peut-être que quelqu'un peut m'aider?

Merci à l'avance

+0

Pourquoi voulez-vous faire cela dans un déclencheur? En supposant un système de production où vous vous souciez de la performance, cela nécessiterait trois déclencheurs et un paquet (ou une table temporaire) ou un déclencheur composé de 11g avec plusieurs parties. C'est généralement une mauvaise solution. Pourriez-vous créer une contrainte qui empêche les trois colonnes d'être NULL, puis modifier l'application pour supprimer la ligne 'located' lorsqu'elle est supprimée de la table parent? –

+0

C'est une tâche que nous devons résoudre pour une conférence. La base de données est fixe et l'utilisation d'un déclencheur est requise. Nous allons probablement résoudre cette tâche avec 3 déclencheurs. Cependant, cette solution est une sorte d'insatisfaction, si vous savez ce que je veux dire ... – Ennosigaeon

Répondre

1

D'abord, FOR EACH ROW ne vous aide pas ici puisque vous ne l'utilisez :new ou :old ne gèrent la ligne spécifique mise à jour. Vous pouvez essayer de supprimer FOR EACH ROW. (Je n'ai pas un environnement pour tester avec désolé maintenant)

Vraiment cela ne semble pas être un bon usage des déclencheurs. Vous pourriez à la place:

  • Toujours suivre lac, rivière, et les suppressions de table de mer avec DELETE FROM located WHERE sea IS NULL AND river IS NULL AND lake IS NULL;
  • Créer des procédures delete_lake, etc. qui suppriment de la table du lac, puis supprimer situé.
  • Plus efficacement, vous devriez effectuer l'une ou l'autre de ces deux approches, mais en commençant par supprimer les lignes (DELETE FROM located WHERE sea {theSeaBeingDeleted} AND river IS NULL AND lake IS NULL;). De cette façon, vous ne mettez pas à jour un ensemble de lignes que vous êtes sur le point de supprimer de toute façon.
Questions connexes