Précédent   Forum des professionnels en informatique > Bases de données > Oracle > SQL
SQL Forum d'entraide sur le SQL pour Oracle
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 17/01/2008, 16h26   #1
Invité de passage
 
Inscription : janvier 2008
Messages : 15
Détails du profil
Informations forums :
Inscription : janvier 2008
Messages : 15
Points : 3
Points : 3
Par défaut MERGE - Pousuivre malgré une erreure

Bonjour à tous,

J'ai actuellement un stored proc qui fonctionne (chargement de donnée dans une table)
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
CREATE OR REPLACE
procedure imp_cap_brand AS
begin
 
declare
error_var integer;
my_select VARCHAR2(4000);
  begin
      DBMS_ERRLOG.CREATE_ERROR_LOG('BRD', 'ERRLOG'); --création de la table de log d'erreur
 
      MERGE INTO BRD  --debut du merge
      USING WK_CAP_MANUFACTURERS WK_BRD
      ON (WK_BRD.MANUFACTURER_CODE=BRD.BRD_ID)
      WHEN MATCHED THEN 
                  UPDATE SET BRD.BRD_NM = WK_BRD.MANUFACTURER_NAME, 
                             BRD.BRD_ABBR = WK_BRD.MANUFACTURER_CAP_CODE_LOOKUP,
                             BRD.BRD_TYP_CD = '001'
      WHEN NOT MATCHED THEN 
                  INSERT (BRD.BRD_ID,BRD.BRD_NM,BRD.BRD_ABBR,BRD.BRD_TYP_CD) 
                  VALUES (WK_BRD.MANUFACTURER_CODE ,WK_BRD.MANUFACTURER_NAME ,WK_BRD.MANUFACTURER_CAP_CODE_LOOKUP, '001')
                  LOG ERRORS INTO errlog ('BRD_MERGE_INSERT');
 
      -- on teste si on a rencontré une erreure durant le merge
      my_select := 'SELECT count(ORA_ERR_NUMBER$) FROM errlog';
      execute immediate(my_select) INTO error_var;
      DBMS_OUTPUT.PUT_LINE(error_var);
 
      IF error_var = 0 
      Then 
        DBMS_OUTPUT.PUT_LINE('Aucune erreure');
      else
        DBMS_OUTPUT.PUT_LINE('Erreure trouvée'); 
      End IF;            
 
      my_select := 'DROP TABLE ERRLOG';
      execute immediate(my_select);
 
      --gestion des erreures c'est là que j aimerai retourné dans le merge
      exception 
      when others then 
            DBMS_OUTPUT.PUT_LINE('Erreure remontée');
            --rollback;  -- rollback la transaction
            --raise; 
  end;
end imp_cap_brand;
Mon souci c'est que à la premiére erreure du merge, Oracle sort de la procédure. Moi j'aimerai parcourir tous le senregistrements et poursuivre malgré une erreure. Pensez vous que c'est possible avec MERGE ?
ArCal est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 17/01/2008, 17h06   #2
Rédacteur/Modérateur
 
Avatar de orafrance
 
Inscription : janvier 2004
Messages : 15 861
Détails du profil
Informations personnelles :
Âge : 35

Informations forums :
Inscription : janvier 2004
Messages : 15 861
Points : 16 212
Points : 16 212
à moins de traiter ligne à ligne avec un curseur ce n'est pas possible... et dans ce cas tu risques de dégrader les perfs

le mieux c'est encore d'éviter les erreurs
orafrance est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 17/01/2008, 17h46   #3
Invité de passage
 
Inscription : janvier 2008
Messages : 15
Détails du profil
Informations forums :
Inscription : janvier 2008
Messages : 15
Points : 3
Points : 3
Bon au final j'ai réussit à faire un truc qui marche. Mon erreure était de créer le fichier de log dans la stored proc en fait je la crée une fois au début et par la suite la vide puis la remplit avec les erreurs:

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
create or replace
procedure imp_cap_brand as
begin
declare
error_var integer;
my_select VARCHAR2(4000);
  begin
      my_select := 'TRUNCATE TABLE errlog';
      execute immediate(my_select);
      
      MERGE INTO BRD
      USING WK_CAP_MANUFACTURERS WK_BRD
      ON (WK_BRD.MANUFACTURER_CODE=BRD.BRD_ID)
      WHEN MATCHED THEN 
                  UPDATE SET BRD.BRD_NM = WK_BRD.MANUFACTURER_NAME, 
                             BRD.BRD_ABBR = WK_BRD.MANUFACTURER_CAP_CODE_LOOKUP,
                             BRD.BRD_TYP_CD = '001'
      WHEN NOT MATCHED THEN 
                  INSERT (BRD.BRD_ID,BRD.BRD_NM,BRD.BRD_ABBR,BRD.BRD_TYP_CD) 
                  VALUES (WK_BRD.MANUFACTURER_CODE ,WK_BRD.MANUFACTURER_NAME ,WK_BRD.MANUFACTURER_CAP_CODE_LOOKUP, '001')
                  LOG ERRORS INTO errlog ('BRD_MERGE_INSERT') REJECT LIMIT UNLIMITED;
 
      -- on teste si on a rencontré une erreure durant le merge
      my_select := 'SELECT count(ORA_ERR_NUMBER$) FROM errlog';
      execute immediate(my_select) INTO error_var;
      DBMS_OUTPUT.PUT_LINE(error_var);
      
      IF error_var = 0 
      Then 
        DBMS_OUTPUT.PUT_LINE('Aucune erreure');
      else
        DBMS_OUTPUT.PUT_LINE('Erreure trouvée'); 
      end IF;            
  end;
end imp_cap_brand;
Le paramétre REJECT LIMIT UNLIMITED sur les update, insert ou merge permet de poursuivre malgré une erreure.

Dans ma table de log j'aurais en cas d'erreure les valeures suivantes:
Code :
1
2
3
4
5
6
SELECT * FROM errlog WHERE rownum < 3
ORA_ERR_NUMBER$        ORA_ERR_MESG$ 
---------------------- -----------------------------------------------------------------------------------------
2291                   ORA-02291: integrity constraint (VCACORE.FK_BRD_BRD_TYP) violated - parent KEY NOT found 
2291                   ORA-02291: integrity constraint (VCACORE.FK_BRD_BRD_TYP) violated - parent KEY NOT found 
2 rows selected
ArCal est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 17/01/2008, 18h12   #4
Rédacteur/Modérateur
 
Avatar de orafrance
 
Inscription : janvier 2004
Messages : 15 861
Détails du profil
Informations personnelles :
Âge : 35

Informations forums :
Inscription : janvier 2004
Messages : 15 861
Points : 16 212
Points : 16 212
ha pas mal, je ne connaissait pas
orafrance 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 06h53.


 
 
 
 
Partenaires

Hébergement Web