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 et d'update ORA-00001


Sujet :

PL/SQL Oracle

  1. #1
    Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2014
    Messages
    2
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2014
    Messages : 2
    Points : 3
    Points
    3
    Par défaut Problème d'insertion et d'update ORA-00001
    Bonjour à toutes et à tous,
    Je suis étudiant en deuxième année de dut informatique, et suis actuellement en période de stage.
    Je sais pertinemment que l'erreur ORA-00001 revient souvent sur les forums cependant n'ayant trouvé aucune réponse à mes questions je me tourne vers vous.

    Actuellement, je développe une routine devant mettre à jour des données lorsqu'un fournisseur existe pour une référence, ou alors si il n'existe pas, insérer ce nouveau fournisseur avec différentes données complémentaires.
    A partir d'un fichier Excel je récupère des données que je place dans une tables temporaires "imp_gco_purchase2_".
    J'utilise un curseur pour parcourir cette table ligne par ligne.

    Lorsque mon fichier excel ne comporte que des insertions cela fonctionne, de même lorsqu'il ne comporte que des éléments à mettre à jours.
    En revanche, lorsqu'il y a des mises à jours et des insertions j'obtiens l'erreur :
    "Error at line 1
    ORA-00001: violation de contrainte unique (C_TEST.GCO_COMPL_DATA_PURCHASE_PK2)
    ORA-06512: à "C_TEST.IMP_GCO_PURCHASE2", ligne 333
    ORA-06512: à ligne 39"


    "Imp_gco_purchase2" correspond a un package comprenant diverses procédures et la ligne 333 correspond à ma procédure d'insertion. J'en conclus que lorsqu'il y a des insert et des update dans mon fichier ma routine n'établit pas de séparation et tente d'insérer les éléments qui ne devraient qu'être mis à jours et de ce fait m'indique une duplication de clé unique.

    Voici mon code :
    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
    DECLARE
     
       PPID VARCHAR(50);
       TMP VARCHAR(50);
       TMP2 INTEGER;
       CURSOR PARCOURLIGNE IS 
       (SELECT * FROM IMP_GCO_PURCHASE2_);
     
     
     
    BEGIN
     
     
       FOR N IN PARCOURLIGNE
       LOOP
     
           C_TEST.IMP_GCO_PURCHASE2.IMP_GCO_PURCHASE2_CTRL;   
     
           BEGIN 
     
               PPID := null;
               TMP := null;
               TMP2 := 0;
     
               SELECT PAC_PERSON_ID into PPID FROM PAC_PERSON where PAC_PERSON.PER_KEY1 = any N.PER_KEY1;
     
               SELECT count(IMP_GCO_PURCHASE2_.PER_KEY1) INTO TMP2 FROM GCO_COMPL_DATA_PURCHASE, IMP_GCO_PURCHASE2_, PAC_PERSON
               WHERE PAC_PERSON.PER_KEY1 = N.PER_KEY1
               AND GCO_COMPL_DATA_PURCHASE.GCO_GOOD_ID IN (SELECT GCO_GOOD_ID FROM GCO_GOOD, IMP_GCO_PURCHASE2_ WHERE GCO_GOOD.GOO_MAJOR_REFERENCE = N.GOO_MAJOR_REFERENCE)
               AND IMP_GCO_PURCHASE2_.GOO_MAJOR_REFERENCE = N.GOO_MAJOR_REFERENCE
               --AND PPID = any GCO_COMPL_DATA_PURCHASE.PAC_SUPPLIER_PARTNER_ID
               AND IMP_GCO_PURCHASE2_.ID = N.ID
               and imp_gco_purchase2_.goo_major_reference in ( select gco_good.goo_major_reference from gco_good where gco_good.gco_good_id = GCO_COMPL_DATA_PURCHASE.gco_good_id)           
               AND PAC_PERSON.PAC_PERSON_ID 
               IN(SELECT PAC_PERSON_ID FROM PAC_PERSON, IMP_GCO_PURCHASE2_ WHERE IMP_GCO_PURCHASE2_.PER_KEY1 = PAC_PERSON.PER_KEY1)
               AND PAC_PERSON.PAC_PERSON_ID = ANY GCO_COMPL_DATA_PURCHASE.PAC_SUPPLIER_PARTNER_ID;
     
     
                IF TMP2 = 0 THEN C_TEST.IMP_GCO_PURCHASE2.IMP_GCO_PURCHASE2_IMPORT;
     
                ELSE 
                C_TEST.IMP_GCO_PURCHASE2.IMP_GCO_PURCHASE2_UPDATE; 
     
                END IF;  
     
                EXCEPTION WHEN NO_DATA_FOUND THEN NULL;
                --EXCEPTION WHEN DUP_VAL_ON_INDEX THEN C_TEST.IMP_GCO_PURCHASE2.IMP_GCO_PURCHASE2_UPDATE;
     
           END;
     
       END LOOP; 
    END;
    J'espère avoir été suffisamment clair et vous remercie d'avance pour votre aide.

  2. #2
    Modérateur
    Avatar de al1_24
    Homme Profil pro
    Retraité
    Inscrit en
    Mai 2002
    Messages
    9 080
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Retraité
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2002
    Messages : 9 080
    Points : 30 801
    Points
    30 801
    Par défaut
    Je ne me suis pas penché sur ta procédure, j'en suis resté à la description de ton problème.

    Et je m'étonne
    Pourquoi faire un traitement à partir d'un curseur alors que deux requêtes ensemblistes pourraient faire l'affaire ?

    Du style :
    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
    UPDATE  cible
    SET (   cible.colonne
        ,   ...
        )
        =   (   SELECT  source.colonne
                    ,   ...
                FROM    source
                WHERE   cible.identifiant = source.identifiant
            )
    WHERE   EXISTS
            (   SELECT  NULL
                FROM    source
                WHERE   cible.identifiant = source.identifiant
            )
    ;
    INSERT INTO cible   
        (   identifiant
        ,   colonne
        ,   ...
        )
    SELECT  source.identifiant
        ,   source.colonne
        , ...
    FROM    source
    WHERE   NOT EXISTS
            (   SELECT  NULL
                FROM    cible
                WHERE   cible.identifiant = source.identifiant
            )
    ;
    Ou encore plus efficacement avec une unique commande MERGE :
    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
    MERGE INTO cible
    USING   source
    ON  (   cible.identifiant = source.identifiant )
    WHEN MATCHED THEN UPDATE
    SET     cible.colonne = source.colonne
        ,   ...
    WHEN NOT MATCHED THEN INSERT
        (   identifiant
        ,   colonne
        ,   ...
        )
    VALUES
        (   source.identifiant
        ,   source.colonne
        ,   ...
        )   
    ;
    Modérateur Langage SQL
    Règles du forum Langage SQL à lire par tous, N'hésitez pas à consulter les cours SQL
    N'oubliez pas le bouton et pensez aux balises
    [code]
    Si une réponse vous a aidé à résoudre votre problème, n'oubliez pas de voter pour elle en cliquant sur
    Aide-toi et le forum t'aidera : Un problème exposé sans mentionner les tentatives de résolution infructueuses peut laisser supposer que le posteur attend qu'on fasse son travail à sa place... et ne donne pas envie d'y répondre.

  3. #3
    Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2014
    Messages
    2
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2014
    Messages : 2
    Points : 3
    Points
    3
    Par défaut
    Merci pour votre réponse Al1_24.
    Je ne connais pas vraiment Merge into mais je vais tenter cette approche et vous redire ce que cela donne.

    D'un autre côté si mon code fonctionne séparément c'est que le problème ne dois pas être énorme, certainement la syntaxe.
    J'aimerais bien si possible aller au bout de cette version procédurale.

    edit : Peut-on utiliser plusieurs tables dans la condition en utilisant merge into ?

    edit : J'ai réussi à faire marcher votre solution avec le merge into bien qu'il me fallait quand même un curseur imbriqué pour éviter la sélection multiple.
    Je vous remercie encore.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [SQL-Server] Problème avec INSERT / UPDATE
    Par abd_aabd dans le forum PHP & Base de données
    Réponses: 23
    Dernier message: 23/08/2011, 01h12
  2. Réponses: 4
    Dernier message: 05/04/2011, 08h32
  3. Problème sur INSERT et UPDATE en même temps
    Par harf18 dans le forum Développement
    Réponses: 2
    Dernier message: 09/12/2009, 15h50
  4. Réponses: 8
    Dernier message: 27/06/2008, 17h29
  5. Réponses: 5
    Dernier message: 25/02/2008, 08h59

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