Précédent   Forum des professionnels en informatique > Bases de données > Oracle
Oracle Forum Oracle : le serveur, les outils, ... Voir F.A.Q Oracle Tutoriels Oracle
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 30/12/2007, 18h43   #1
Invité de passage
 
Inscription : décembre 2007
Messages : 13
Détails du profil
Informations forums :
Inscription : décembre 2007
Messages : 13
Points : 2
Points : 2
Par défaut Trigger annulation delete

Bonjour,

Je souhaite créer un trigger pour recréer une ligne supprimée.

Explication :

Une application peut être amenée à supprimer des lignes dans une table A. Désormais, je dois garder une trace de cette suppression. Pour cela, j'ai créé un nouveau champ IS_DELETE dans ma table A. Il n'est pas possible de modifier l'application existante (remplacer l'ordre "DELETE FROM A WHERE ID = ...) par UPDATE A SET IS_DELETE = 'Y' WHERE ID = ...).

Je pensais donc utiliser un trigger mais j'ai un problème de table mutante.

J'ai même essayé d'utiliser une table temporaire et d'utiliser deux trigger mais cela ne fonctionne pas.

Script 1er trigger :

Code :
1
2
3
4
5
6
7
8
9
CREATE OR REPLACE TRIGGER TRG_IS_DELETE1
  BEFORE DELETE ON A
  FOR EACH ROW
BEGIN	
 
INSERT INTO A_TEMP (ID,IS_DELETE) VALUES (:old.ID,'Y');
 
END;
/

Script 2ème trigger :

Code :
1
2
3
4
5
6
7
8
9
10
11
12
CREATE OR REPLACE TRIGGER TRG_IS_DELETE2
  AFTER INSERT ON A_TEMP
  FOR EACH ROW
BEGIN	
 
INSERT INTO A (ID,IS_DELETE)
SELECT ID, IS_DELETE FROM A_TEMP;
 
DELETE FROM A_TEMP;
 
END;
/
Je ne sais plus trop comment m'en sortir. J'aurai aimé le gérer avec un seul trigger sans table temporaire mais j'ai l'impression que ce n'est pas possible.

De plus, avec 2 triggers et une table temporaire, je n'y arrive même pas.

Quelqu'un peut-il m'aider ?

Merci
lupizzz est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 02/01/2008, 06h08   #2
Membre éprouvé
 
Inscription : décembre 2007
Messages : 354
Détails du profil
Informations personnelles :
Localisation : France

Informations forums :
Inscription : décembre 2007
Messages : 354
Points : 408
Points : 408
Indépendamment du problème de table mutante et étant donné que l'application ne peut pas être modifiée cette solution n'est pas acceptable! En fait, avez-vous pené aux interrogations sur cette table? Y a-t-il des aggrégats dans cette application sur cette table? Beaucoup de choses peuvent mal tourner dans cette application à cause de cette modification.
Michel SALAIS est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 02/01/2008, 10h42   #3
Invité de passage
 
Inscription : décembre 2007
Messages : 13
Détails du profil
Informations forums :
Inscription : décembre 2007
Messages : 13
Points : 2
Points : 2
Oui, il peut y avoir des agregats mais sans incidence car les agrégations se font uniquement sur des enregistrements qui ne peuvent pas être supprimées (il y a un champ particulier dans cette table).

J'ai conscience qu'il peut y avoir des effets de bord non prévu et j'ai prévenu de les alerter sur ce point. (Je te rejoins)

Mais je me demandais simplement si cela était déjà possible avec mes deux triggers (ou un seul). J'ai l'impression que c'est impossible (j'ai fait beaucoup de tests mais, à chaque fois, j'ai une erreur)

Si c'est impossible, la question de la dangerosité ne se pose même plus.

Merci
lupizzz est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 02/01/2008, 10h51   #4
Membre éprouvé
 
Avatar de chrifo
 
Inscription : juillet 2006
Messages : 445
Détails du profil
Informations forums :
Inscription : juillet 2006
Messages : 445
Points : 418
Points : 418
Bonjour,
A ce moment là, pourquoi ne pas gérer la suppression logique non pas avec ce champ is_delete, mais en concervant les éléments supprimés dans une autre table ( --> votre table temporaire n'est plus temporaire, 1 seul trigger) ?
chrifo est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 02/01/2008, 10h58   #5
Invité de passage
 
Inscription : décembre 2007
Messages : 13
Détails du profil
Informations forums :
Inscription : décembre 2007
Messages : 13
Points : 2
Points : 2
En fait, l'idée c'est de pouvoir visualiser à partir d'une application les données même si la ligne a été supprimée.

En fait, il y a deux applications :
- une qui peut être amener à supprimer un enregistrement
- une qui visualise les enregistrements
lupizzz est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 02/01/2008, 11h51   #6
Membre éprouvé
 
Inscription : décembre 2007
Messages : 354
Détails du profil
Informations personnelles :
Localisation : France

Informations forums :
Inscription : décembre 2007
Messages : 354
Points : 408
Points : 408
Citation:
Envoyé par lupizzz Voir le message
Oui, il peut y avoir des agregats mais sans incidence car les agrégations se font uniquement sur des enregistrements qui ne peuvent pas être supprimées (il y a un champ particulier dans cette table).

J'ai conscience qu'il peut y avoir des effets de bord non prévu et j'ai prévenu de les alerter sur ce point. (Je te rejoins)

Mais je me demandais simplement si cela était déjà possible avec mes deux triggers (ou un seul). J'ai l'impression que c'est impossible (j'ai fait beaucoup de tests mais, à chaque fois, j'ai une erreur)

Si c'est impossible, la question de la dangerosité ne se pose même plus.

Merci
Ta solution n'est pas valable ...
Voici un exemple qui montre comment faire
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
 
SET echo ON
 
DROP TABLE test
 
DROP TABLE test succeeded.
CREATE TABLE test ( a number, b number)
 
CREATE TABLE succeeded.
INSERT INTO test VALUES (1, 0)
 
1 rows inserted
INSERT INTO test VALUES (2, 0)
 
1 rows inserted
DROP TABLE test_temp
 
DROP TABLE test_temp succeeded.
CREATE global TEMPORARY TABLE test_temp
ON commit preserve rows
AS SELECT * FROM test
WHERE 1 = 0
 
CREATE global succeeded.
CREATE OR REPLACE TRIGGER t1
before DELETE
ON test
FOR each row
begin
  INSERT INTO test_temp VALUES (:old.a, 1);
end;
 
TRIGGER t1 Compiled.
CREATE OR REPLACE TRIGGER t2
after DELETE
ON test
begin
  INSERT INTO test
  SELECT * FROM test_temp;
  DELETE test_temp;
end;
 
TRIGGER t2 Compiled.
DELETE test
 
2 rows deleted
SELECT * FROM test
 
A                      B                      
---------------------- ---------------------- 
1                      1                      
2                      1                      
 
2 rows selected
Il est également possible de passer par un tableau dans un package à la place de la table temporaire ...
Michel SALAIS est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 02/01/2008, 12h49   #7
Membre du Club
 
Inscription : février 2007
Messages : 69
Détails du profil
Informations forums :
Inscription : février 2007
Messages : 69
Points : 42
Points : 42
Citation:
J'ai même essayé d'utiliser une table temporaire et d'utiliser deux trigger mais cela ne fonctionne pas.
peu tu donner plus de detail?
adiltyane est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 02/01/2008, 14h14   #8
Invité de passage
 
Inscription : décembre 2007
Messages : 13
Détails du profil
Informations forums :
Inscription : décembre 2007
Messages : 13
Points : 2
Points : 2
Effectivement, cela fonctionne parfaitement.

J'étais sur une mauvaise piste en voulant utiliser un trigger sur ma table temporaire.

Merci beaucoup pour la solution.
lupizzz est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité Cette discussion est résolue.
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 02h59.


 
 
 
 
Partenaires

Hébergement Web