Précédent   Forum des professionnels en informatique > Bases de données > Oracle > PL/SQL
PL/SQL Forum d'entraide sur le PL/SQL
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 07/11/2006, 14h23   #1
Invité de passage
 
Inscription : novembre 2006
Messages : 5
Détails du profil
Informations forums :
Inscription : novembre 2006
Messages : 5
Points : 1
Points : 1
Par défaut Erreur Dans Procedure Pl/sql

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 :
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.
Redwings est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 07/11/2006, 14h53   #2
Membre Expert
 
Inscription : avril 2005
Messages : 1 672
Détails du profil
Informations forums :
Inscription : avril 2005
Messages : 1 672
Points : 1 337
Points : 1 337
Pourquoi ne pas encapsuler votre instruction INSERT qui génère l'erreur dans un bloc :
Code :
1
2
3
4
5
6
BEGIN
  INSERT ...
EXCEPTION WHEN -- erreur Oracle de violation de clé primaire en l'occurence
  <traitement>;
END;
...
Magnus est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 07/11/2006, 15h12   #3
Invité de passage
 
Inscription : novembre 2006
Messages : 5
Détails du profil
Informations forums :
Inscription : novembre 2006
Messages : 5
Points : 1
Points : 1
Citation:
Envoyé par Magnus
Pourquoi ne pas encapsuler votre instruction INSERT qui génère l'erreur dans un bloc :
Merci... Je teste en direct...........
..........................
..........................
Mince, ça ne fonctionne pas...
ça me met

ORA-00001: violation de contrainte unique (PK_ITRRUBFLUAMORT)
ORA-06512: à ligne 39

Mon code modifié est :
Code :
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
 
...
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_char(cItrrubfluamortRec.ifadtdeb,'MM')!= to_char(cItrrubfluamortRec.ifadtfin,'MM') THEN
            BEGIN
            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
                  );
            EXCEPTION WHEN OCI_ERROR THEN 
            dbms_output.put_line('Code    erreur : '||to_char(SQLCODE));
            dbms_output.put_line('Libellé erreur : '||to_char(SQLERRM));
            dbms_output.put_line('Itrid          : '||nItrid);
            dbms_output.put_line('Iruordre       : '||nIruordre);
            END;
...
Redwings est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 07/11/2006, 15h29   #4
Invité de passage
 
Inscription : novembre 2006
Messages : 5
Détails du profil
Informations forums :
Inscription : novembre 2006
Messages : 5
Points : 1
Points : 1
En fait la proposition m'a donné une idée et celà a marché!!!
J'ai en fait testé le code SQL et comme je faisaid un viol de PK c'est -1, si je trouvais ce code je faisais un DBMS_OUTPUT.PUT_LINE de mes variables....
Je peux comme ça débugger ma fonction

MERCI!!!
Redwings est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 07/11/2006, 15h30   #5
Rédacteur

 
Avatar de SheikYerbouti
 
Inscription : mai 2003
Messages : 6 533
Détails du profil
Informations forums :
Inscription : mai 2003
Messages : 6 533
Points : 6 469
Points : 6 469
testez plutôt l'exception suivante:

Code :
1
2
When DUP_VAL_ON_INDEX Then
  ...
__________________
Rédacteur Oracle (Oracle ACE)
Guide Oracle ,Guide PL/SQL, Guide Forms 9i/10g, Index de recherche
Je ne réponds pas aux questions techniques par MP
Blogs: Forms-PL/SQL-J2EE - Forms Java Beans
SheikYerbouti est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 07/11/2006, 15h40   #6
Invité de passage
 
Inscription : novembre 2006
Messages : 5
Détails du profil
Informations forums :
Inscription : novembre 2006
Messages : 5
Points : 1
Points : 1
Exact!! ça marche, c'est plus propre effectivement, mon IF est donc bien imbriqué (comme le proposait Magnus), et je teste bien cette exception DUP_VAL.... et celà fonctionne.
Merci à tous...
Redwings est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité Cette discussion est résolue.
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 14h44.


 
 
 
 
Partenaires

Hébergement Web