Bonjour !
Je me trouve coincé dans une mise à jour qui me paraissait jusqu'ici simple. En effet, je voulais reproduire la mise à jour manuelle par un automate. J'ai deux tables :
tb_Hist_Entretienet une autre table tb_CalendrierCREATE TABLE TB_HIS_ENTRETIEN (
NUMERO_ENTRETIEN BIGINT NOT NULL,
DATE_INTER DATE NOT NULL,
DATE_PANNE DATE,
CODE_ORGANE VARCHAR(20),
CODE_ENTRETIEN SMALLINT,
CAUSE VARCHAR(20),
DATE_PREV DATE,
APPRECIATION_ENTRETIEN VARCHAR(20),
HEURE_MARCHE_CUMUL SMALLINT,
INTERVENANT VARCHAR(50) DEFAULT 'STAFF ONA STEP',
N_ODS VARCHAR(9),
TEMPS_ARRET_MACHINE_H SMALLINT,
TEMPS_INTERVENTION_H SMALLINT,
PIECE_RECHANGE_DA SMALLINT,
MAIN_DOEUVRE_DA SMALLINT,
TOTAL_DA BIGINT,
CUMMUL_DA SMALLINT
);
ALTER TABLE TB_HIS_ENTRETIEN ADD CONSTRAINT PK_TB_HIS_ENTRETIEN PRIMARY KEY (NUMERO_ENTRETIEN);
Aussi, j'ai crée deux déclencheurs ; un sur la table tb_Hist_Entretien et un autre sur la table tb_Calendrier.CREATE TABLE TB_CALENDRIER (
CODE_ORGANE VARCHAR(20) NOT NULL,
CODE_ENTRETIEN VARCHAR(2) NOT NULL,
DATE_PREVISIONNELLE DATE NOT NULL,
NATURE_ENTRETIEN VARCHAR(10) NOT NULL,
NUMERO_ENTRETIEN BIGINT
);
ALTER TABLE TB_CALENDRIER ADD CONSTRAINT FK_TB_CALENDRIER_1 FOREIGN KEY (NUMERO_ENTRETIEN) REFERENCES TB_HIS_ENTRETIEN (NUMERO_ENTRETIEN) ON DELETE CASCADE ON UPDATE CASCADE;
Le seul problème avec ce déclencheur est dans cette partie :
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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112 CREATE OR ALTER trigger tb_his_entretien_bi for tb_his_entretien active before insert or update position 0 AS declare variable V1 varchar(1); declare variable V2 varchar(3); declare variable V3 varchar(5); declare variable cmp smallint; declare variable v_num_ods varchar(9); declare variable freq varchar(20); declare variable p_v2 smallint; declare variable v_date_int date; declare variable nb_fois smallint; declare variable code_org varchar(16); declare variable code_entre smallint; declare variable date_previs date; declare variable n_ordre_entretien smallint; BEGIN nb_fois = 2; IF (NEW.NUMERO_ENTRETIEN IS NULL) THEN NEW.NUMERO_ENTRETIEN = GEN_ID(GEN_TB_HIS_MAIN_ID,1); /* Extraction de l'année */ V3 = '/' || cast(Extract(year from new.date_inter) as varchar(4)); /* compter le nbr d'enregitrements selon les deux critères */ select count(oe.code_etretien), max(oe.frequence), max(oe.code_organe), max(oe.code_etretien) from tb_organe_entretien oe where (oe.code_organe = new.code_organe and oe.code_etretien = new.code_entretien) into :cmp, :freq, :code_org, :code_entre; /* si choix est CEP (calendrier d'entretin préventif) */ if (new.cause = 'CEP') then begin /* si le nombre d'enregistrements est différents de 0 */ /* donc la table comprend des entretiens */ if (cmp = 0) then exception Erreur_Entretien_Introuvable; /* reseiger dans une variable locale le type d'ODS */ V1 = 'P'; end else V1 = 'C'; /* si corredctive alors vérifier la date de la panne */ if ((new.cause <> 'CEP') and (new.date_panne is null)) then exception erreur_date_panne; if (inserting) then begin select max(h.n_ods), max(h.date_inter) from tb_his_entretien h where (substring(h.n_ods from 1 for 1) =: V1) into :v_num_ods, :v_date_int; /* s'assurer de la date entrée */ if (new.date_inter < v_date_int) then exception erreur_date_courrante; /* formuler le code de l'ODS */ V2 = '001'; if (v_num_ods <> '') then begin V2 = substring(v_num_ods from 2 for 3); p_v2 = cast(v2 as smallint); p_v2 = p_v2 + 1; V2 = cast(p_v2 as varchar(3)); if (char_length(V2) = 2) then V2 = '0' || V2; if (char_length(V2) = 1) then V2 = '00' || V2; end /* renseigner l'info dans la champ approprié */ new.n_ods = coalesce(V1,'') || coalesce(V2,'') || coalesce(V3,''); end if (freq = 'MENSUEL') then begin new.date_prev = dateadd(30 day to new.date_inter); nb_fois = 24; end if (freq = 'TRIMESTRIEL') then begin new.date_prev = dateadd(91 day to new.date_inter); nb_fois = 8; end if (freq = 'SEMESTRIEL') then begin new.date_prev = dateadd(182 day to new.date_inter); nb_fois = 4; end if (freq = 'ANNUEL') then new.date_prev = dateadd(365 day to new.date_inter); date_previs = new.date_prev; /* manque test */ cmp = 0; select count(*) from tb_calendrier cc where (cc.code_organe = :code_org) into :cmp; if (nb_fois <> cmp) then begin n_ordre_entretien = 1; while (nb_fois >= 1) do begin insert into tb_calendrier (code_organe, code_entretien, date_previsionnelle) values (:code_org, :code_entre,:date_previs); if (freq = 'MENSUEL') then date_previs = dateadd(1 month to date_previs); if (freq = 'TRIMESTRIEL') then date_previs = dateadd(3 month to date_previs); if (freq = 'SEMESTRIEL') then date_previs = dateadd(6 month to date_previs); if (freq = 'ANNUEL') then date_previs = dateadd(12 month to date_previs); nb_fois = nb_fois - 1; n_ordre_entretien = n_ordre_entretien + 1; end end END
Cette table contient le champ {NUMERO_ENTRETIEN} qui doit être renseigné automatiquement lors d'une insertion dans la table tb_Hist_Entretien, pour cela j'ai dû créer un déclencheur de type After sur la table tb_Calendrier afin de mettre à jour la ligne en cours :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 insert into tb_calendrier (code_organe, code_entretien, date_previsionnelle) values (:code_org, :code_entre,:date_previs);
Le problème :
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 CREATE OR ALTER trigger tb_calendrier_ai0 for tb_calendrier active after insert position 0 AS declare variable c_org varchar(20); declare variable c_entretien smallint; declare variable d_prev date; declare variable n_entretien bigint; begin select hh.code_organe, hh.code_entretien, hh.numero_entretien, hh.date_prev from tb_his_entretien hh where (hh.numero_entretien = (select max(hs.numero_entretien) from tb_his_entretien hs)) into :c_org, :c_entretien, :n_entretien, :d_prev; update tb_calendrier c set c.numero_entretien = :n_entretien where (c.code_organe =:c_org and c.code_entretien =:c_entretien and c.date_previsionnelle =:d_prev); end
- Quant j'insère la 1ère ligne dans la table tb_Hist_Entretien, je remarque que le champ {NUMERO_ENTRETIEN} de la table tb_Calendrier prend la valeur Null;
- Au delà de la 1ère ligne, le champ {NUMERO_ENTRETIEN} prend une valeur n-1 ? comme si, la nouvelle ligne n'a pas subit de commit et n'est pas visible par la base de données c'est pourquoi cette valeur null quand j'insère la 1ère ligne.
Je voudrais savoir s'il est possible de forcer le commit avant l'appel du déclencheur tb_calendrier_ai0 ?
S'il est possible de faire plus simple je suis aussi preneur.
Merci à tous....
Partager