Bonjour à tous,
J'écris une petite procédure stockée pour calculer automatiquement un classement et j'ai un problème que je ne comprends pas.
Lorsque j'exécute ma procédure par un CALL, une seule ligne est affectée et j'ai l'impression que mon curseur c_resParSerie ne renvoie plus rien après le premier parcours...
Alors que, lorsque j'exécute ma procédure avec le logiciel Debugger for MySQL, tout fonctionne correctement...
Si vous avez des idées, je suis preneur ...
Je vous mets la construction de mes tables et ma procédure dessous...
Et la procédure
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 CREATE TABLE Clubs( IdClub varchar(8) NOT NULL, NomClub varchar(50)NOT NULL, CONSTRAINT PK_Clubs PRIMARY KEY(IdClub) ); CREATE TABLE Epreuves( IdEp int NOT NULL, CodeBat varchar(5)NOT NULL, NomEp varchar(50)NULL, DateEp date NULL, ClubOrga varchar(5), CoId int NULL, NbInscrits int NULL, CONSTRAINT PK_Epreuves PRIMARY KEY(IdEp) ); ALTER TABLE Epreuves ADD CONSTRAINT FK_Epreuve_ClubOrga FOREIGN KEY (ClubOrga) REFERENCES Clubs (IdClub); CREATE TABLE Inscrits( Licence varchar(8)NOT NULL, Nom varchar(50)NULL, Prenom varchar(50)NULL, Club varchar(8) NULL, Sexe char(1)NULL, CONSTRAINT PK_Inscrits PRIMARY KEY(Licence) ); ALTER TABLE Inscrits ADD CONSTRAINT FK_Club_Inscrits FOREIGN KEY(Club) REFERENCES Clubs(IdClub); CREATE TABLE Participe( Licence varchar(8)NOT NULL, NbEprCour int, CodeBat varchar(5)NOT NULL, CONSTRAINT PK_Participe PRIMARY KEY(Licence) ); ALTER TABLE Participe ADD CONSTRAINT FK_Participe_Licence FOREIGN KEY(Licence)REFERENCES Inscrits( Licence ); CREATE TABLE Resultats( Licence varchar(8)NOT NULL, IdEp int NOT NULL, Rang int NOT NULL ); ALTER TABLE Resultats ADD CONSTRAINT Pk_Resultats PRIMARY KEY(Licence, IdEp); ALTER TABLE Resultats ADD CONSTRAINT FK_Resultats_Licence FOREIGN KEY(Licence)REFERENCES Inscrits( Licence ); ALTER TABLE Resultats ADD CONSTRAINT FK_Resultats_EpId FOREIGN KEY(IdEp)REFERENCES Epreuves( IdEp ); CREATE TABLE GEN21( Licence varchar(8)NOT NULL, Rang int NOT NULL, CodeBat varchar(5)NOT NULL, Retrait int NOT NULL DEFAULT 0, CONSTRAINT PK_GEN21 PRIMARY KEY(Licence) ); ALTER TABLE GEN21 ADD CONSTRAINT FK_GEN21_Licence FOREIGN KEY(Licence)REFERENCES Inscrits( Licence ); INSERT INTO Epreuves(IdEp, NomEp, CodeBat)VALUES(1,'1', 'BAT'); INSERT INTO Epreuves(IdEp, NomEp, CodeBat)VALUES(2,'2', 'BAT'); INSERT INTO Epreuves(IdEp, NomEp, CodeBat)VALUES(3,'3', 'BAT'); INSERT INTO Epreuves(IdEp, NomEp, CodeBat)VALUES(4,'4', 'BAT'); INSERT INTO Epreuves(IdEp, NomEp, CodeBat)VALUES(5,'5', 'BAT'); INSERT INTO Epreuves(IdEp, NomEp, CodeBat)VALUES(6,'6', 'BAT'); INSERT INTO Epreuves(IdEp, NomEp, CodeBat)VALUES(7,'7', 'BAT'); INSERT INTO Inscrits(licence)VALUES('1'); INSERT INTO Inscrits(licence)VALUES('2'); INSERT INTO Inscrits(licence)VALUES('3'); INSERT INTO Resultats(idep, licence, rang)VALUES(1, '1', 1); INSERT INTO Resultats(idep, licence, rang)VALUES(1, '2', 2); INSERT INTO Resultats(idep, licence, rang)VALUES(1, '3', 3); INSERT INTO Resultats(idep, licence, rang)VALUES(2, '1', 1); INSERT INTO Resultats(idep, licence, rang)VALUES(2, '2', 2); INSERT INTO Resultats(idep, licence, rang)VALUES(2, '3', 3); INSERT INTO Resultats(idep, licence, rang)VALUES(3, '2', 1); INSERT INTO Resultats(idep, licence, rang)VALUES(3, '3', 2); INSERT INTO Resultats(IdEp, Licence, Rang) VALUES('4','1','1'); INSERT INTO Resultats(IdEp, Licence, Rang) VALUES('4','2','2'); INSERT INTO Resultats(IdEp, Licence, Rang) VALUES('4','3','3'); INSERT INTO Resultats(IdEp, Licence, Rang) VALUES('5','1','1'); INSERT INTO Resultats(IdEp, Licence, Rang) VALUES('5','2','2'); INSERT INTO Resultats(IdEp, Licence, Rang) VALUES('5','3','3'); INSERT INTO Resultats(IdEp, Licence, Rang) VALUES('6','1','1'); INSERT INTO Resultats(IdEp, Licence, Rang) VALUES('6','2','2'); INSERT INTO Resultats(IdEp, Licence, Rang) VALUES('6','3','3'); INSERT INTO Resultats(IdEp, Licence, Rang) VALUES('7','1','1'); INSERT INTO Resultats(IdEp, Licence, Rang) VALUES('7','2','2'); INSERT INTO Resultats(IdEp, Licence, Rang) VALUES('7','3','3');
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
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264 DELIMITER // DROP PROCEDURE IF EXISTS classement// CREATE PROCEDURE classement (IN p_bateau varchar(50)) BEGIN -- ============================================================= -- ======= DECLARATIONS ======================================== -- ============================================================= -- VARIABLES -- DECLARE v_lic char(8); /*Var licence*/ DECLARE v_nbpart int; /*Var nb épreuves courues*/ DECLARE v_rang int; /*Rang sans DNC*/ DECLARE v_totalepr int; /*nb d'épreuves total*/ DECLARE v_message varchar(50); DECLARE v_epreuve int; -- Id Epreuve DECLARE v_inscrits int; -- nombre de coureurs par course DECLARE v_penalite int; -- penalité pour DNC DECLARE v_pirecourse int; -- Rang le plus grand dans la table résultats DECLARE v_pirepenalite int; -- Penalité la plus élevée DECLARE v_pirepenalite2 int; -- 2e penalité la plus élevée DECLARE v_retrait int; -- Retrait précédent DECLARE done INT DEFAULT FALSE; -- Pour bouclage curseurs -- CURSEURS -- DECLARE c_part CURSOR FOR /*Curseur pour nb participation*/ SELECT Licence, Count(Licence) As Particip FROM Resultats INNER JOIN Epreuves On Resultats.IdEp=Epreuves.IdEp Where Epreuves.CodeBat=p_bateau Group By Licence; DECLARE c_resParSerie CURSOR FOR /*Curseur liste résultats par code bateau et somme par licence*/ SELECT Licence, Sum(Rang) As Classement FROM Resultats INNER JOIN Epreuves WHERE Resultats.IdEp=Epreuves.IdEp AND Epreuves.CodeBat=p_bateau Group By Licence Order by Classement ASC; DECLARE c_listeEpr CURSOR FOR /*Curseur liste des épreuves*/ SELECT DISTINCT IdEp FROM Epreuves; DECLARE c_EprNonCourues CURSOR FOR -- Curseur liste épreuves dans Epreuves mais pas dans Résultat(Licence) SELECT IdEp FROM Epreuves WHERE CodeBat=p_bateau AND IdEp NOT IN (SELECT IdEp FROM Resultats WHERE Licence=v_lic); /*Sauf les id qui sont déjà dans résultats*/ DECLARE c_LicGen CURSOR FOR -- Curseur licences du général /bateau SELECT Licence FROM GEN21 WHERE CodeBat=p_bateau; -- HANDLER -- DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE; -- Déclencheur pour sortir des boucles des curseurs DELETE FROM Participe WHERE CodeBat = p_bateau; DELETE FROM GEN21 WHERE CodeBat = p_bateau; /*==========================================-- -- Inser. Nb participation dans Participe -- --==========================================*/ OPEN c_part; loopc_part: LOOP FETCH FROM c_part INTO v_lic, v_nbpart; IF done THEN LEAVE loopc_part; END IF; INSERT INTO Participe(Licence, NbEprCour, CodeBat) VALUES (v_lic, v_nbpart, p_bateau); END LOOP; CLOSE c_part; SET done = FALSE; /*===================================-- --Nombre de coureurs par épreuve-- --===================================*/ OPEN c_listeEpr; loopc_listeEpr: LOOP FETCH FROM c_listeEpr INTO v_epreuve; IF done THEN LEAVE loopc_listeEpr; END IF; UPDATE Epreuves SET NbInscrits = (SELECT Count(Licence) FROM Resultats WHERE IdEp = v_epreuve) WHERE IdEp = v_epreuve; END LOOP; CLOSE c_listeEpr; SET done = FALSE; -- ===================================== -- Calcul général avec pénalités abs -- -- ===================================== OPEN c_resParSerie; loopc_resParSerie: LOOP FETCH FROM c_resParSerie INTO v_lic, v_rang; -- Calcul général /lic (/bat) IF done THEN LEAVE loopc_resParSerie; END IF; SELECT NbEprCour INTO v_nbpart FROM Participe WHERE Licence = v_lic; /*Nombre d'épreuves courues /lic*/ SELECT COUNT(IdEp) INTO v_totalepr FROM Epreuves WHERE CodeBat=p_bateau; /*Nombre d'épreuves validées /bat*/ -- ANCHOR remplace nbpart par totalepr si courses validées -- ======================== -- IF v_nbpart = v_totalepr THEN -- SANS PENALITE D'ABSCENCE -- -- ======================== -- INSERT INTO GEN21(Licence, Rang, CodeBat) VALUES (v_lic, v_rang, p_bateau); /*Pas de pénalité*/ -- ----------------------- -- -- DISCARDS SANS PENALITES -- -- ----------------------- -- IF v_nbpart >= 3 THEN -- RETRAIT DE L'EPREUVE LA PLUS MAUVAISE SELECT Rang INTO v_pirecourse FROM Resultats WHERE Licence = v_lic AND -- Détermine et enregistre rang le plus grand IdEp IN (SELECT IdEp FROM Epreuves WHERE CodeBat=p_bateau) ORDER BY Rang DESC LIMIT 1; -- Limite le résulats à 1 ligne UPDATE GEN21 SET Retrait = v_pirecourse WHERE Licence = v_lic AND CodeBat = p_bateau; UPDATE GEN21 SET Rang = (v_rang - v_pirecourse) WHERE Licence = v_lic AND CodeBat = p_bateau; END IF; IF v_nbpart >= 5 THEN -- RETRAIT DE LA 2e EPREUVE LA PLUS MAUVAISE SELECT Rang INTO v_pirecourse FROM Resultats WHERE Licence = v_lic AND -- Détermine et enregistre rang le plus grand IdEp IN (SELECT IdEp FROM Epreuves WHERE CodeBat=p_bateau) ORDER BY Rang DESC LIMIT 1, 1; -- OFFSET 1 et LIMITE LE NB DE LIGNE à 1 SELECT Retrait INTO v_retrait FROM GEN21 WHERE Licence = v_lic; UPDATE GEN21 SET Retrait = (v_pirecourse + v_retrait) WHERE Licence = v_lic AND CodeBat = p_bateau; UPDATE GEN21 SET Rang = (v_rang - (v_pirecourse + v_retrait)) WHERE Licence = v_lic AND CodeBat = p_bateau; END IF; -- ======================================== -- ELSE -- CALCUL RANG & PENALITES POUR LES ABSENTS -- SET v_penalite = 0; -- ======================================== -- SET v_pirepenalite = 0; SET v_pirepenalite2 = 0; OPEN c_EprNonCourues; loopc_EprNonCourues: LOOP -- Boucle sur les épreuves qui n'ont pas été courues /licence FETCH FROM c_EprNonCourues INTO v_epreuve; IF done THEN LEAVE loopc_EprNonCourues; END IF; SELECT COUNT(Licence) INTO v_inscrits FROM Resultats WHERE IdEp = v_epreuve; /*Nombre d'inscrits dans l'épreuve*/ SET v_penalite = v_penalite + v_inscrits + 3; IF v_pirepenalite < (v_inscrits + 3) THEN SET v_pirepenalite = (v_inscrits + 3); END IF; END LOOP; Close c_EprNonCourues; SET done = FALSE; SELECT NbInscrits INTO v_pirepenalite2 FROM Epreuves WHERE CodeBat='BAT' AND IdEp NOT IN (SELECT IdEp FROM Resultats WHERE Licence='1') ORDER BY NbInscrits DESC LIMIT 1,1; SET v_pirepenalite2 = v_pirepenalite2 + 3; SET v_rang=v_rang + v_penalite; INSERT INTO GEN21(Licence, Rang, CodeBat) VALUES (v_lic, v_rang, p_bateau); /*Ajout des penalité*/ -- ================================== -- -- Traitement DISCARDS avec pénalités -- -- ================================== -- IF v_nbpart >= 3 THEN -- RETRAIT 1re EPREUVE PLUS MAUVAISE SELECT Rang INTO v_pirecourse FROM Resultats WHERE Licence = v_lic AND -- Détermine et enregistre rang le plus grand IdEp IN (SELECT IdEp FROM Epreuves WHERE CodeBat=p_bateau) ORDER BY Rang DESC LIMIT 1; -- Limite le résulats à 1 ligne IF v_pirecourse >= v_pirepenalite THEN -- rang course > penalité UPDATE GEN21 SET Retrait = v_pirecourse WHERE Licence = v_lic AND CodeBat = p_bateau; UPDATE GEN21 SET Rang = (v_rang - v_pirecourse) WHERE Licence = v_lic AND CodeBat = p_bateau; ELSE -- penalité > rang course UPDATE GEN21 SET Retrait = v_pirepenalite WHERE Licence = v_lic AND CodeBat = p_bateau; UPDATE GEN21 SET Rang = (v_rang - v_pirepenalite) WHERE Licence = v_lic AND CodeBat = p_bateau; END IF; END IF; IF v_nbpart >= 5 THEN -- RETRAIT DE LA 2e EPREUVE LA PLUS MAUVAISE SELECT Rang INTO v_pirecourse FROM Resultats WHERE Licence = v_lic AND -- Détermine et enregistre rang le plus grand IdEp IN (SELECT IdEp FROM Epreuves WHERE CodeBat=p_bateau) ORDER BY Rang DESC LIMIT 1, 1; -- OFFSET 1 et LIMITE LE NB DE LIGNE à 1 SELECT Retrait INTO v_retrait FROM GEN21 WHERE Licence = v_lic; IF v_pirecourse >= v_pirepenalite2 OR v_pirepenalite2 = 3 THEN -- rang course > penalité2 UPDATE GEN21 SET Retrait = (v_pirecourse + v_retrait) WHERE Licence = v_lic AND CodeBat = p_bateau; UPDATE GEN21 SET Rang = (v_rang - (v_pirecourse + v_retrait)) WHERE Licence = v_lic AND CodeBat = p_bateau; ELSE -- penalité > rang course UPDATE GEN21 SET Retrait = (v_retrait + v_pirepenalite2) WHERE Licence = v_lic AND CodeBat = p_bateau; UPDATE GEN21 SET Rang = (v_rang - (v_retrait + v_pirepenalite2)) WHERE Licence = v_lic AND CodeBat = p_bateau; END IF; END IF; END IF; END LOOP; Close c_resParSerie; SET done = FALSE; END // DELIMITER ;
Partager