Voici mon problème.
La table "QUESTIONNAIRES" contient une colonne qui spécifie un numéro d'ORDRE.
Avant une insertion ou une modification d'un enregistrement de la table "QUESTIONNAIRES", il faut que le système effectue un décalage (incémentation de 1) de la colonne d'ordre pour tous les enregistrements de la table QUESTIONNAIRES qui ont un ordre plus grand ou égal à l'ordre que je suis en train de modifier ou insérer.
La première idée est de réaliser un trigger BEFORE INSERT OR UPDATE sur la table questionnaire du style:
Cette tentative n’est pas fonctionnel et renvoie l’erreur de la table en mutation. En effet, on ne peut pas mettre à jour des tuples d’une table que l’on est en train de modifier!
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10 CREATE OR REPLACE TRIGGER TR_ORDRE_VAR BEFORE INSERT OR UPDATE ON QUESTIONNAIRES FOR EACH ROW BEGIN UPDATE QUESTIONNAIRES SET ORDRE = ORDRE+1 WHERE ... //jointure adéquoite AND ORDRE >=:NEW.ORDRE;
Pour contourner cette problèmatique, j'essaie de mettre en oeuvre un trigger qui envoi ma commande d'update dans une table ORDRE_SQL. Cette table est ensuite vidée toutes les 2 seconde par une procédure exécuter par le programmateur (scheduler) Oracle (sorte de réplication asymétrique asynchrone mais sur la même table).
Cette solution n'est pas loin de fonctionner. Mais avant d'aller plus loin, j'aimerais savoir si quelqu'un a une meilleur idée???
Merci.
P.S.: Si vous n'avez pas de meilleures ideés, vous pouvez peut-être me dire pourquoi la désactivation d'une contrainte pose problème dans un trigger.
renvoie l'erreur suivante:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11 CREATE OR REPLACE TRIGGER TR_ORDRE_VAR BEFORE INSERT OR UPDATE ON QUESTIONNAIRES FOR EACH ROW DECLARE VL_ORDRE_SQL VARCHAR2(2000); BEGIN . . . ALTER TABLE QUESTIONNAIRES DISABLE CONSTRAINT QRE_ORDRE_UK; ...
PS'': L'article http://sgbd.developpez.com/oracle/ora-04091/ parle de l'erreur de la table mutante, mais je n'ai pas trouvé de solution à mon problème dans cet article...
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9 PLS-00103: Symbole "ALTER" rencontré à la place d'un des symboles suivants : begin case declare exit for goto if loop mod null pragma raise return select update while with <an identifier> <a double-quoted delimited-identifier> <a bind variable> << close current delete fetch lock insert open rollback savepoint set sql execute commit forall merge <a single-quoted SQL string> pipe![]()
Voilà, merci.
Partager