Bonjour,

J'ai un problème de verrous que je ne parviens pas a résoudre (certainement par manque d'expérience avec Oracle).

Tout d'abord j'ai une table PARTICIPATION :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
CREATE TABLE PARTICIPATION
(
  COURSE_ID   NUMBER                            NOT NULL,
  SPORTIF_ID  NUMBER                            NOT NULL,
  DOSSARD     NUMBER                            NOT NULL,
  TEMPS       NUMBER(5,2)
);
Cette table sert a définir quel sportif participe a quelle course ainsi que sont temps réalisé (NULL si la course n'as pas encore eu lieu).

Par ailleurs j'ai une table PODIUM :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
CREATE TABLE PODIUM
(
  COURSE_ID    NUMBER                           NOT NULL,
  SPORTIF_ID   NUMBER                           NOT NULL,
  MEDAILLE_ID  VARCHAR2(1 BYTE)                 NOT NULL
);
La table Podium permet de définir une médaille d'or, d'argent ou de bronze.

J'ai une procédure stockée qui permet de vérifier si tout les temps sont enregistré pour une course (et donc savoir si il est possible de faire le podium).

Cette procédure est :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
FUNCTION CHECK_VALID_COURSE (P_COURSE_ID IN NUMBER) RETURN BOOLEAN
	IS
	NB_PARTICIPANT NUMBER;
	NB_TEMPS_SAISI NUMBER;
	BEGIN
		SELECT COUNT(*), COUNT(TEMPS)
		INTO NB_PARTICIPANT, NB_TEMPS_SAISI
		FROM PARTICIPATION
		WHERE COURSE_ID = P_COURSE_ID;
 
		RETURN (NB_PARTICIPANT = NB_TEMPS_SAISI);
	END;
Une autre procédure permet de générer le podium en fonction des temps :
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
PROCEDURE GEN_PODIUM_COURSE (P_COURSE_ID IN NUMBER)
	IS
	UN_SPORTIF_ID NUMBER;
	UN_TEMPS NUMBER;
	CPT NUMBER;
	ID_MEDAILLE VARCHAR2(1);
 
	CURSOR LIST_PARTICIPATIONS_BY_TEMPS
		IS
		SELECT SPORTIF_ID, TEMPS
		FROM PARTICIPATION
		WHERE COURSE_ID = P_COURSE_ID
		ORDER BY TEMPS DESC;
 
	BEGIN
		CLEAR_PODIUM_COURSE(P_COURSE_ID);
		CPT := 0;
		OPEN LIST_PARTICIPATIONS_BY_TEMPS;
 
		FETCH LIST_PARTICIPATIONS_BY_TEMPS
		INTO UN_SPORTIF_ID, UN_TEMPS;
 
		WHILE (LIST_PARTICIPATIONS_BY_TEMPS%FOUND AND CPT < 3)
		LOOP
 
			CASE CPT
				WHEN 0 THEN ID_MEDAILLE := 'O';
				WHEN 1 THEN ID_MEDAILLE := 'A';
				WHEN 2 THEN ID_MEDAILLE := 'B';
			END CASE;
 
			INSERT INTO PODIUM (COURSE_ID, SPORTIF_ID, MEDAILLE_ID)
			VALUES (P_COURSE_ID, UN_SPORTIF_ID, ID_MEDAILLE);
 
			FETCH LIST_PARTICIPATIONS_BY_TEMPS
			INTO UN_SPORTIF_ID, UN_TEMPS;
			CPT := CPT + 1;
		END LOOP;
 
		CLOSE LIST_PARTICIPATIONS_BY_TEMPS;
	END;
Tout ceci est testé et sûr.

Maintenant abordons le problème.

Je souhaiterais que la génération des podium soit automatique a la saisie du temps.
Donc qu'un trigger a l'insert et a l'update d'un temps génère le podium.

voici le trigger :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
CREATE OR REPLACE TRIGGER T_CREATE_PODIUM
AFTER INSERT OR UPDATE
ON PARTICIPATION
FOR EACH ROW
BEGIN
	IF (PKG_PODIUM.CHECK_VALID_COURSE(:NEW.COURSE_ID)) THEN
		PKG_PODIUM.GEN_PODIUM_COURSE(:NEW.COURSE_ID);
	END IF;
END;
Le problème est que PKG_PODIUM.CHECK_VALID_COURSE réalise un SELECT sur PARTICIPATION, et que cette dernière est exécuté à l'insert ou mise a jour sur PARTICIPATION.
Oracle me refuse donc son exécution puisque apparemment la table PARTICIPATION est vérouillée.

Comment ferez vous pour contourner ce problème ?
Ça fait un moment que je cherche une solution propre mais je ne trouve rien.

Merci par avance.