bonjour,
je veux faire un trigger qui bloque l'insertion dans une table pour certaine valeurs, et faire l'insertion dans une autre table. merci bcp![]()
bonjour,
je veux faire un trigger qui bloque l'insertion dans une table pour certaine valeurs, et faire l'insertion dans une autre table. merci bcp![]()
Bonjour,
Qu'as tu déjà essayé ?
quelle sont tes initiatives.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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 CREATE OR REPLACE TRIGGER AR.RA_INTERFACE_AFTER_INSERT BEFORE INSERT ON RA_INTERFACE_LINES_ALL REFERENCING NEW AS New OLD AS Old FOR EACH ROW DECLARE v_type varchar2(10); exception_1 exception; BEGIN select distinct ractta.type into v_type from ar.ra_batch_sources_all rbsa,ar.ra_cust_trx_types_all ractta where rbsa.name = :NEW.batch_source_name and ractta.cust_trx_type_id = :NEW.cust_trx_type_id and rbsa.org_id = :NEW.org_id; if ( :NEW.org_id=158 and :NEW.INTERFACE_LINE_ATTRIBUTE4='0' and :NEW.INTERFACE_LINE_CONTEXT='ORDER ENTRY' and v_type='INV') then INSERT INTO RANDA.SMT_RA_INTERFACE_LINES_ALL (LINE_ID, ... ) VALUES (:NEW.LINE_ID, ... ); raise exception_1; end if; EXCEPTION WHEN exception_1 THEN RAISE; END RA_INTERFACE_AFTER_INSERT; /
Quelques soit la solution que l’on vous proposera ici, n’oubliez pas de la considérer d’un point de vue concurrentiel. Vous savez bien qu’en Oracle les selects (sans clause for update) ne bloquent pas les update/delete/insert et vice versa. Imaginez un instant que lors de l’exécution de votre trigger par un utilisateur user1, le select suivant:
retourne bien un v_type = ‘INV’ ceci malgré le fait qu’un autre utilisateur, user2, l’ait déjà modifiée entre temps en lui attribuant une valeur ‘VNI’ mais sans atteindre la partie commit de son code. Le select exécuté par user1 va se rendre compte que la valeur a été modifiée mais pas encore ‘’commitée’’ et va donc utiliser les ‘’rollbacks segments ‘’ correspondants pour reconstruire l’image qu’avait le type au moment de l’exécution du select ci-dessous c'est-à-dire ‘INV’. Votre trigger va alors continuer et insérer dans la table
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8 SELECT DISTINCT ractta.type INTO v_type FROM ar.ra_batch_sources_all rbsa ,ar.ra_cust_trx_types_all ractta WHERE rbsa.name = :NEW.batch_source_name AND ractta.cust_trx_type_id = :NEW.cust_trx_type_id AND rbsa.org_id = :NEW.org_id;
Mais manque de chance, le user2, juste après cet insert commit son travail et hop !!! vous avez quand même inséré une ligne dans la table SMT_RA_INTERFACE_LINES_ALL alors qu’il ne le fallait pas.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 SMT_RA_INTERFACE_LINES_ALL
D’une manière générale deux conseils sur les triggers:
- N’oubliez jamais de penser à l’aspect concurrentiel lors du développement d’un trigger
- Lorsque vous vous trouvez devant une logique qui vous semble compliquée à implémenter, il y a des chances dans ce cas que le trigger ne représente pas la place adéquate pour cette logique
Partager