IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

PL/SQL Oracle Discussion :

Problème d'insertion avec une procédure PLSQL


Sujet :

PL/SQL Oracle

  1. #1
    Membre à l'essai
    Inscrit en
    Juin 2005
    Messages
    31
    Détails du profil
    Informations forums :
    Inscription : Juin 2005
    Messages : 31
    Points : 22
    Points
    22
    Par défaut Problème d'insertion avec une procédure PLSQL
    Bonjour,



    Dans le cadre de mon travail, je maintiens une application qui reçoit des données d'une autre application.


    Les données reçues sont envoyées vers une table ENTREE, via une procédure PLSQL.

    Depuis quelques temps, 99% des transactions se font correctement.

    Mais pour une poignée d'entre elles, ca ne passe pas.
    Et on m'a demandé pourquoi en me précisant bien "c'est toujours sur les 3 ou 4 mêmes clients que ca bloque"


    Du coup, j'ai regardé la tête des données qui transitent de l'application en amont de la mienne (j'ai accès à l'historique des lignes envoyées chez moi).
    J'ai fait une comparaison ligne_qui_passe vs ligne_qui_passe_pas, sans rien trouver d'intéressant.

    J'ai regardé le procédure PLSQL, sans rien trouver de flagrant.


    Du coup, je me suis créé une table de LOG, et dans la procédure PLSQL, j'ai collé plein d'INSERT INOT MA_TABLE_DE_LOG, avec la date, l'heure, le nom du client.

    Selon les endroits, j'ai rajouté au bout de mon INSERT un flag qui me dit où il est passé dans la procédure.

    Donc, pour une ligne qui passe, j'ai des lignes dans ma table qui reessemblent à:


    COMMENTAIRES

    3 - entrée: 102085 | client: TOTO | 28/02/2012 03:02:14 | APPEL PROCEDURE
    4 - entrée: 102085 | client: TOTO | 28/02/2012 03:02:14 | INSERTION
    5 - entrée: 102085 | client: TOTO | 28/02/2012 03:03:01 | APPEL PROCEDURE
    6 - entrée: 102085 | client: TOTO | 28/02/2012 03:03:01 | MISE A JOUR
    7 - entrée: 102086 | client: TUTU | 28/02/2012 03:12:19 | APPEL PROCEDURE
    8 - etc ...

    Comme ça, je peux voir que le 28 à 15:02:14, la procédure a été appelée, que quasimment instantanément, il y a eu une insertion et que 47 sec plus tard, un utilisateur a du changer une donnée sur son écran, qui se répercute chez moi par un 2ème lancement de la procédure + un update (la ligne a déjà été crée, donc on UPDATE)

    J'ai laissé tourner le bazar quelques jours et rebellote "Il nous manque des lignes".

    Je vais voir ma log: aux heures indiquées, je vois bien les appels, les INSERT/UPDATE.

    Je me suis donc dit que l'INSERT devait peut être merdouiller quelque part.

    Je me suis donc rajouté une partie EXCEPTION à la fin de la procédure PLSQL, pour piéger les éventuelles erreurs.
    Je teste ça sur ma base de dev, je maltraite quelques données pour insérer des doublons, faire rentrer des VARCHAR dans des NUMBER, etc

    Ca marche.

    En cas d'erreur, j'aurias une ligne horodatée, avec le SQLCODE, SQLERRM, etc

    De plus, je crée un trigger sur ma table ENTREE: à chaque insertion ou udpate, je rajoute une ligne dans ma table de log avec horodatage, type d'action (INS/UPD), etc ...

    Je valide tout ça et je laisse tourner.

    Rerebelote, il manque des lignes.

    Je vais fouiner dans ma table de log et je constate que, comme précédemment, ma procédure PLSQL s'est bien lancée, et qu'elle est passé par les instructions d'insert/update.
    Je constate aussi que le trigger à l'insertion s'est bien déclenché comme le dit la ligne: 28/02/2012 03:02:30 | TRIG INS | Entrée 102085

    Et par contre, pas de ligne d'erreur/exception.


    Et quand je vais voir dans ma table, à l'heure donnée, pour le client donnée, il n'y a aucune ligne...

    En résumé:
    [*] Ma procédure se lance correctement.[*] Elle donne bien l'ordre d'insertion/update[*] Aucune erreur n'est détectée[*] Le trigger se déclenche

    => Plein de rien dans ma table entrée...


    Je ne sais pas où chercher ....


    Si vous avez des idées, des trucs à me faire tester, défoulez vous

    Merci d'avance.

  2. #2
    Membre éclairé
    Profil pro
    Inscrit en
    Février 2010
    Messages
    412
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2010
    Messages : 412
    Points : 807
    Points
    807
    Par défaut
    Question bete, il y a un commit?

    Je veux dire, pour inserer des logs, il faut que ce soit via une "autonomous_transaction". Sinon en cas d'echec, les logs sont annules en meme temps que s'effectue le rollback de la transaction complete.

    Et meme avec les triggers, selon ou ils sont mis, ce n'est pas dit que vous voyez ce qu'il se passe:
    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
    drop trigger tmp_trig1;
    drop trigger tmp_trig2;
    drop table tmp;
    drop table tmp2;
    drop table tmp3;
    create table tmp(n number primary key);
    create table tmp2(log_date timestamp, vc varchar2(20));
    exec dbms_errlog.create_error_log('TMP','tmp3');
     
    create or replace procedure tmp_proc(p_text varchar2) is
       pragma autonomous_transaction;
    begin
       insert into tmp2 values (current_timestamp,p_text);
       commit;
    end;
    /
    show errors
     
    create trigger tmp_trig1
    before insert on tmp 
    for each row
    begin
       tmp_proc('before'||:new.n);
    end;
    /
    show errors
     
    create trigger tmp_trig2
    after insert on tmp 
    for each row
    begin
       tmp_proc('after'||:new.n);
    end;
    /
    show errors
     
    insert into tmp values (1);
    exec dbms_lock.sleep(0.1);
    insert into tmp values (1);
    select * from tmp2 order by log_date;
    Avec le resultat suivant:
    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
     
    1 row created.
     
    Elapsed: 00:00:00.16
     
    PL/SQL procedure successfully completed.
     
    Elapsed: 00:00:00.10
    insert into tmp values (1)
    *
    ERROR at line 1:
    ORA-00001: unique constraint (TMP.SYS_C007793) violated
     
     
    Elapsed: 00:00:00.00
     
    LOG_DATE                                                                    VC
    --------------------------------------------------------------------------- -----------
    28-FEB-12 05.18.02.163000 PM                                                before1
    28-FEB-12 05.18.02.236000 PM                                                after1
    28-FEB-12 05.18.02.338000 PM                                                before1
     
    Elapsed: 00:00:00.00
    Si on ne garde que le after insert, on ne sait pas qu'on a tente d'inserer une seconde fois la valeur 1. Et si on ne garde que le before, on ne sait pas qu'insertion a echoue.

    Alors qu'oracle a deja des choses de pretes:
    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
    TMP@MINILHC >insert into tmp values (42) log errors into tmp3 ('oups');
     
    1 row created.
     
    Elapsed: 00:00:00.00
    TMP@MINILHC >exec dbms_lock.sleep(0.1);
     
    PL/SQL procedure successfully completed.
     
    Elapsed: 00:00:00.10
    TMP@MINILHC >insert into tmp values (42) log errors into tmp3 ('oups');
    insert into tmp values (42) log errors into tmp3 ('oups')
    *
    ERROR at line 1:
    ORA-00001: unique constraint (TMP.SYS_C007792) violated
     
     
    Elapsed: 00:00:00.10
    TMP@MINILHC >select * from tmp2 order by log_date;
     
    LOG_DATE                                                                    VC
    --------------------------------------------------------------------------- --------------------
    28-FEB-12 05.17.30.305000 PM                                                before42
    28-FEB-12 05.17.30.305000 PM                                                after42
    28-FEB-12 05.17.30.405000 PM                                                before42
     
    6 rows selected.
     
    Elapsed: 00:00:00.00
    TMP@MINILHC >select * from tmp3;
     
    ORA_ERR_NUMBER$
    ---------------
    ORA_ERR_MESG$
    -----------------------------------------------------------------------------------------------------------------
    -----------------------------------------------------------------------------------------------------------------
    ----------------------------------------------------------------------------------------------------
    ORA_ERR_ROWID$
    -----------------------------------------------------------------------------------------------------------------
    -----------------------------------------------------------------------------------------------------------------
    ----------------------------------------------------------------------------------------------------
    OR
    --
    ORA_ERR_TAG$
    -----------------------------------------------------------------------------------------------------------------
    -----------------------------------------------------------------------------------------------------------------
    ----------------------------------------------------------------------------------------------------
    N
    -----------------------------------------------------------------------------------------------------------------
    -----------------------------------------------------------------------------------------------------------------
    ----------------------------------------------------------------------------------------------------
                  1
    ORA-00001: unique constraint (TMP.SYS_C007792) violated
     
    I
    oups
    42
     
     
    Elapsed: 00:00:00.00
    Ca peut etre une piste...

  3. #3
    Membre à l'essai
    Inscrit en
    Juin 2005
    Messages
    31
    Détails du profil
    Informations forums :
    Inscription : Juin 2005
    Messages : 31
    Points : 22
    Points
    22
    Par défaut
    Merci pour la réponse.


    Du coup, j'ai mis 2 triggers sur ma table.

    Un trigger before et un after.

    Et ...

    Les 2 se déclenchent, et pourtant rien n'est inséré.


    Et quand je "force" en mettant des commit; sans mon code, j'obtiens un
    "ORA-02064: opération distribuée non supportée"

  4. #4
    Membre chevronné
    Homme Profil pro
    Chef de projet MOA
    Inscrit en
    Février 2012
    Messages
    652
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Morbihan (Bretagne)

    Informations professionnelles :
    Activité : Chef de projet MOA
    Secteur : Distribution

    Informations forums :
    Inscription : Février 2012
    Messages : 652
    Points : 1 878
    Points
    1 878
    Par défaut
    Questions bêtes n°2
    - Ton déclencheur de "trace" est appelé aussi pour les instructions DELETE ?
    - Les UPDATE ne toucheraient-ils pas aux PK de tes tables ?

    Et qu'est-ce qu'il se passe si tu relances l'intégration uniquement pour les enregistrements qui ont disparus ?

  5. #5
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Customer Success Manager @Vertica
    Inscrit en
    Septembre 2008
    Messages
    8 452
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Customer Success Manager @Vertica
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2008
    Messages : 8 452
    Points : 17 820
    Points
    17 820
    Par défaut
    Avez-vous implémenter précisément ceci ?
    Citation Envoyé par Rams7s Voir le message
    pour inserer des logs, il faut que ce soit via une "autonomous_transaction". Sinon en cas d'echec, les logs sont annules en meme temps que s'effectue le rollback de la transaction complete.

  6. #6
    Membre éclairé
    Profil pro
    Inscrit en
    Février 2010
    Messages
    412
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2010
    Messages : 412
    Points : 807
    Points
    807
    Par défaut
    Dans l'exemple que je donne oui, non?

Discussions similaires

  1. [2.x] [Doctrine 2] Problème d'insertion avec une relation manytomany
    Par Khalezis dans le forum Symfony
    Réponses: 0
    Dernier message: 14/11/2013, 12h56
  2. [2.x] Problème d'insertion avec une relation ManyToMany
    Par touffifou dans le forum Symfony
    Réponses: 0
    Dernier message: 15/05/2013, 17h39
  3. Réponses: 19
    Dernier message: 13/02/2013, 16h21
  4. Problème d'insertion avec une requête sql
    Par dutty_pi dans le forum JDBC
    Réponses: 5
    Dernier message: 14/03/2012, 13h58
  5. Réponses: 2
    Dernier message: 06/12/2006, 08h54

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo