2009-12-15 5 views
0

Je souhaite développer une procédure pour le scénario suivant.gestion des erreurs/exceptions dans Oracle

J'ai une source, une cible et une table d'erreur. Les tables Target et Error contiennent tous les champs présents dans les tables source. Mais le type de données de tous les champs pour la table d'erreur est varchar. La table d'erreur n'a pas d'intégrité, de clé étrangère et d'autres contraintes. La table d'erreurs comporte également deux autres champs: Erreur no et message d'erreur. Maintenant, lorsque la procédure est exécutée en cas d'erreur lors de l'insertion d'un enregistrement dans la cible, cet enregistrement doit être déplacé vers la table d'erreurs. Le code d'erreur de la base de données et le message d'erreur doivent également être consignés dans les champs des tables d'erreurs, comme indiqué.

Comment puis-je développer une telle procédure?

Exemple de schéma de la table:

source table 
    src(id number 
     ,name varchar2(20) 
     , ...) 

target table 
    tgt(id number 
     ,name varchar2(20) not null 
     , ...) 

error table 
    err (id varchar2(255) 
      ,name varchar2(255) 
      , ... 
      , errno varchar2(255) 
      , errmsg varchar2(255)) 
+0

Quelle version d'Oracle utilisez-vous? En outre, pourriez-vous expliquer whey que vous voulez utiliser un mécanisme si horrible pour charger des données quand Oracle fournit plusieurs alternatives plus élégantes? – APC

+0

Si vous vous interrogez sur les erreurs logiques dans les données sources, et non sur les erreurs pouvant être détectées par le SGBD, consultez l'instruction MERGE, par ex. ici: http://www.psoug.org/reference/merge.html – ThinkJet

Répondre

4

Avez-vous regardé propre fonctionnalité de journalisation des erreurs d'Oracle?

http://download.oracle.com/docs/cd/B19306_01/server.102/b14231/tables.htm#ADMIN10261

+0

David, je pense que vous avez posté le mauvais lien - je ne peux pas voir la pertinence de celui-ci? –

+0

Hmmm, étrange. Cela a fonctionné pour moi même maintenant quand j'ai cliqué dessus. Doit être quelque chose de la technologie. corrigé ... merci Tony. –

+0

lire les réponses est comme le mien "Astuce Oracle quotidienne du jour" – David

0

Procédures de le faire pourrait ressembler à ceci:

procedure ins_tgt(p_id in number, p_name in varchar2, ...) is 
    v_errno number; v_errmsg varchar2(2000); 
begin 
    insert into tgt(id, name, ...) values (p_id, p_name, ...); 
exception 
    when others then 
    /* copy sqlcode and sqlerrm into variables since they can't be used directly in a SQL statement */ 
    v_errno := sqlcode; 
    v_errmsg := sqlerrm; 
    insert into err(id, name, errno, errmsg) values (p_id, p_name, v_errno, v_errmsg); 
end; 


procedure copy_src_tgt is 
begin 
    for s in (select * from src) loop 
    ins_tgt(s.id, s.name, ...); 
    end loop; 
end; 

mais il semble comme une horrible façon inefficace de copier les données d'une table à l'autre ...

+0

@ammonQ: Merci d'avoir répondu. Pouvez-vous me suggérer un code efficace? Je suis nouveau à pl/sql. – user223541

+0

Le moyen efficace de le faire est "insérer dans tgt select * from src where ...", en vérifiant tout ce qui pourrait mal tourner (nulls non admis, valeurs trop longues, etc.) dans la clause where. Oui, cela signifie probablement que vous devez mettre beaucoup de travail dans la déclaration ... BTW, si ma réponse est utile, vous pourriez vouloir upvote et/ou l'accepter. –

+0

Pour consigner les erreurs (qui n'arrivent jamais, mais qui se produiraient si vous essayiez d'insérer dans tgt), vous utilisez la même chose: insert dans err (...) select (..., -1, 'name ne doit pas être null ') de src où le nom est null; etc. –

0
CREATE OR REPLACE PACKAGE BODY foo_dml IS 

    PROCEDURE log_err (
     p_sqlcode IN NUMBER, 
     p_sqlerrm IN VARCHAR2, 
     p_src  IN foo%ROWTYPE 
    ) IS 
     -- inserts the input row to the err log 
    BEGIN 
     INSERT INTO err (
      errno, 
      errmsg, 
      ID, 
      NAME, 
      ... 
     ) VALUES (
      p_sqlcode, 
      p_sqlerrm, 
      p_src.id, 
      p_src.name, 
      ... 
     ); 
    END; 

    PROCEDURE copy_to_tgt (
     p_src IN foo%ROWTYPE 
    ) IS 
     -- copies the input row to the tgt table 
    BEGIN 
     INSERT INTO 
      tgt 
     VALUES 
      p_src; 
    EXCEPTION 
     WHEN OTHERS THEN 
      log_err(SQLCODE, SQLERRM, p_src); 
    END; 

END; 
/
+0

@kusosch: Merci d'avoir répondu. Est-ce que ce code effieent alors celui suggéré par ammoQ. – user223541

+0

fondamentalement le même code, juste arrangé un peu différemment – kurosch