Bonjour à tous,
Je suis en train d'executer une procédure SQL, et j'ai une violation de clé primaire sur un INSERT.
Je voulais savoir comment gérer cette erreur (dans une exception??) pour récupérer les valeurs qui me font planté mon traitement.
Ci-desssous le code (le plantage se fait sur le premier INSERT après 15 minutes de traitement. C'est une table assez lourde...):

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
DECLARE
  NITRID             NUMBER;
   NIRUORDRE          NUMBER;
   NIRFORDRE          NUMBER;
   NIFAANNEE          NUMBER;
   DIFADTDEB          DATE;
   DIFADTFIN          DATE;
   NIFADOTLIN         NUMBER;
   NIFADOTLINMODIF    NUMBER;
   NIFAMTPROV64       NUMBER;
   NIFAMTPROV64MODIF  NUMBER;
   CURSOR CITRRUBFLUAMORT IS 
     SELECT   ITRID,
              IRUORDRE,
              IRFORDRE,
              IFAANNEE,
              IFADTDEB,
              IFADTFIN,
              IFADOTLIN,
              IFAMTPROV64
     FROM     ITRRUBFLUAMORT
     WHERE    (ITRID,IRUORDRE,IRFORDRE,IFAANNEE,IFADTDEB) NOT IN (SELECT DISTINCT ITRID,
                                                                                  IRUORDRE,
                                                                                  IRFORDRE,
                                                                                  IFAANNEE,
                                                                                  IFADTDEB
                                                                  FROM   ITRRUBFLUAMORT
                                                                  WHERE  TO_CHAR(IFADTDEB,'ddmm') NOT IN ('0101','0104','0107','0110')
                                                                         AND TO_CHAR(IFADTDEB,'mm') != TO_CHAR(IFADTFIN,'mm'))
              AND (ITRID,IRUORDRE,IRFORDRE,IFAANNEE,IFADTDEB) NOT IN (SELECT DISTINCT ITRID,
                                                                                      IRUORDRE,
                                                                                      IRFORDRE,
                                                                                      IFAANNEE,
                                                                                      IFADTDEB
                                                                      FROM   ITRRUBFLUAMORT
                                                                      WHERE  TO_CHAR(IFADTDEB,'mm') = TO_CHAR(IFADTFIN,'mm'))
     ORDER BY ITRID,
              IRUORDRE,
              IRFORDRE,
              IFAANNEE,
              IFADTDEB;
BEGIN
  FOR CITRRUBFLUAMORTREC IN CITRRUBFLUAMORT LOOP
    NITRID := CITRRUBFLUAMORTREC.ITRID;
 
    NIRUORDRE := CITRRUBFLUAMORTREC.IRUORDRE;
 
    NIRFORDRE := CITRRUBFLUAMORTREC.IRFORDRE;
 
    NIFAANNEE := CITRRUBFLUAMORTREC.IFAANNEE;
 
    DIFADTDEB := CITRRUBFLUAMORTREC.IFADTDEB;
 
    DIFADTFIN := CITRRUBFLUAMORTREC.IFADTFIN;
 
    NIFADOTLIN := CITRRUBFLUAMORTREC.IFADOTLIN;
 
    NIFAMTPROV64 := CITRRUBFLUAMORTREC.IFAMTPROV64;
 
    NIFADOTLINMODIF := ROUND(CITRRUBFLUAMORTREC.IFADOTLIN / 3,2);
 
    NIFAMTPROV64MODIF := ROUND(CITRRUBFLUAMORTREC.IFAMTPROV64 / 3,2);
 
    IF TO_NUMBER(TO_CHAR(CITRRUBFLUAMORTREC.IFADTDEB,'MM')) != TO_NUMBER(TO_CHAR(CITRRUBFLUAMORTREC.IFADTFIN,'MM')) THEN
      INSERT INTO ITRRUBFLUAMORT
                 (ITRID,
                  IRUORDRE,
                  IRFORDRE,
                  IFAANNEE,
                  IFADTDEB,
                  IFADTFIN,
                  IFADOTLIN,
                  IFAMTPROV64)
      VALUES     (NITRID,
                  NIRUORDRE,
                  NIRFORDRE,
                  NIFAANNEE,
                  ADD_MONTHS(ADD_MONTHS(LAST_DAY(DIFADTDEB),-1) + 1,1),
                  LAST_DAY(ADD_MONTHS(ADD_MONTHS(LAST_DAY(DIFADTDEB),-1) + 1,1)),
                  NIFADOTLINMODIF,
                  NIFAMTPROV64MODIF);
 
      INSERT INTO ITRRUBFLUAMORT
                 (ITRID,
                  IRUORDRE,
                  IRFORDRE,
                  IFAANNEE,
                  IFADTDEB,
                  IFADTFIN,
                  IFADOTLIN,
                  IFAMTPROV64)
      VALUES     (NITRID,
                  NIRUORDRE,
                  NIRFORDRE,
                  NIFAANNEE,
                  ADD_MONTHS(ADD_MONTHS(LAST_DAY(DIFADTDEB),-1) + 1,2),
                  LAST_DAY(ADD_MONTHS(ADD_MONTHS(LAST_DAY(DIFADTDEB),-1) + 1,2)),
                  NIFADOTLIN - (NIFADOTLINMODIF + NIFADOTLINMODIF),
                  NIFAMTPROV64 - (NIFAMTPROV64MODIF + NIFAMTPROV64MODIF));
 
      UPDATE ITRRUBFLUAMORT A
      SET    IFADOTLIN = NIFADOTLINMODIF,
             IFAMTPROV64 = NIFAMTPROV64MODIF,
             IFADTFIN = LAST_DAY(DIFADTDEB)
      WHERE  A.ITRID = CITRRUBFLUAMORTREC.ITRID
             AND A.IRUORDRE = CITRRUBFLUAMORTREC.IRUORDRE
             AND A.IRFORDRE = CITRRUBFLUAMORTREC.IRFORDRE
             AND A.IFAANNEE = CITRRUBFLUAMORTREC.IFAANNEE
             AND A.IFADTDEB = CITRRUBFLUAMORTREC.IFADTDEB;
    END IF;
  END LOOP;
END;
/
Balises de mise en forme ajoutée par Magnus. Merci d'y penser à l'avenir.