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

DB2 Discussion :

Utilisation de l'instruction MERGE


Sujet :

DB2

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Juillet 2005
    Messages
    157
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2005
    Messages : 157
    Par défaut Utilisation de l'instruction MERGE
    Bonjour à tous,

    Je souhaite simplement avoir une information. Je viens d'avoir connaissance de l'instruction MERGE et j'aimerais savoir si je peux l'utiliser de la façon suivante :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    --pour initialiser le code contrat 0715, on concatène à 0715 les derniers chiffres du code créance 0312 correspondant
                SET DecCodeContrat715 = '0715'||substr(DecCodeContrat312_C2,5,16);
     
                MERGE INTO decompte_poste D1
                    USING (select dec_code_contrat, dec_code_poste, dec_type_decompte, dec_code_client, dec_mt_poste, dec_mt_restant, 
                    dec_type_tiers, dec_code_tiers FROM decompte_poste) D2
                    ON (D1.dec_code_contrat = DecCodeContrat715
                    AND D1.dec_code_poste = DecCodePoste)
                WHEN MATCHED THEN
                    UPDATE SET D1.dec_mt_poste = D1.dec_mt_poste + DecMtPoste, D1.dec_mt_restant = D1.dec_mt_restant + DecMtRestant;
                WHEN NOT MATCHED THEN
                    UPDATE SET D1.dec_code_contrat = DecCodeContrat715;
    En gros, je voudrais savoir si je peux exécuter un UPDATE dans la clause 'WHEN NOT MATCHED' au lieu d'un INSERT.

  2. #2
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Sr. Specialist Solutions Architect @Databricks
    Inscrit en
    Septembre 2008
    Messages
    8 454
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Sr. Specialist Solutions Architect @Databricks
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2008
    Messages : 8 454
    Par défaut
    Non, et ça n'aurait d'ailleurs aucun sens.
    Le WHEN NOT MATCHED signifie qu'Oracle n'a pas trouvé de correspondance entre les lignes sources et cibles.
    Dès lors, quelle ligne devrait-il mettre à jour ?

    Ce que vous voulez faire je pense c'est un simple UPDATE non ?

  3. #3
    Membre Expert
    Inscrit en
    Août 2009
    Messages
    1 073
    Détails du profil
    Informations forums :
    Inscription : Août 2009
    Messages : 1 073
    Par défaut
    WHEN NOT MATCHED signifie que la source n'a pas trouvé de correspondance pour la cible ; SQL Server a introduit la condition inverse (WHEN NOT MATCHED BY SOURCE), ce qui a quand même du sens intuitivement : si je veux comparer deux ensembles, je vais bien avoir des correspondances, et des éléments présents dans le 1er mais pas de le 2nd d'une part, et dans le 2nd mais pas dans le 1er d'autre part.
    Cela dit, ce n'est (à ma connaissance) pas possible directement sous Oracle !

    => Il faudra faire un UPDATE ... WHERE NOT EXISTS ...

  4. #4
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Sr. Specialist Solutions Architect @Databricks
    Inscrit en
    Septembre 2008
    Messages
    8 454
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Sr. Specialist Solutions Architect @Databricks
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2008
    Messages : 8 454
    Par défaut
    Je ne vois toujours pas comment mettre à jour une ligne qu'on ne trouve pas.

  5. #5
    Expert confirmé Avatar de mnitu
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2007
    Messages
    5 611
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Octobre 2007
    Messages : 5 611
    Par défaut
    De tout façon il faut que @merlubreizh lise la doc pour MERGE et quelques exemples d’utilisation, parce que sa manière de l’employer montre quelques problèmes de compréhension de cette instruction.

  6. #6
    Membre confirmé
    Profil pro
    Inscrit en
    Juillet 2005
    Messages
    157
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2005
    Messages : 157
    Par défaut
    Bonjour et merci pour vos différents retours

    Je vous explique grosso modo ce que j'essaye de faire dans ma table decompte_poste. Dans cette table, j'ai des champs dec_code_contrat (chaine) et dec_code_poste (chaine) qui constituent la clé primaire. Dec_code_contrat contient des codes de créances dont il faut que je modifie une partie seulement de la chaine.

    Les 4 premiers chiffres du code créance correspondent au code agence, les autres chiffres au code client. Or, deux des agences ont fusionné (code agence 0000 et code agence 1111). L'agence 1111 a absorbé l'agence 0000. Les clients possèdent le même numéro dans les deux agences.

    Seulement, pour une créance 0000xxx donnée et pour un code poste donné, il se peut que la créance 1111xxx avec le même code poste existe déjà, mais avec des montants dec_mt_poste et dec_mt_restant différents.

    Ma logique est donc la suivante. Pour chaque créance 0000xxx et pour chaque code poste, je recherche si la créance 1111xxx correspondante avec le même code poste existe. Si c'est le cas, je souhaite mettre à jour les champs dec_mt_restant et dec_mt_poste de la créance 1111xxx sur ce code poste, puis supprimer l'enregistrement courant. Si l'enregistrement courant n'existe pas, je souhaite mettre à jour le code créance, qui ne commencera plus par '0000' mais par '1111'.

    Exemple

    dec_code_contrat : 00001298502
    dec_code_poste : 80
    dec_mt_poste : 1200.35
    dec_mt_restant : 1200.35

    Je recherche si le code 11111298502 avec le code poste 80 existe déjà. Si c'est le cas, je mets à jour les montants sur ce code 11111298502 et code poste 80. S'il n'existe pas, je mets à jour le code contrat.



    PS : je précise que la base de données est de type DB2 et j'utilise SQL Developer comme éditeur.

  7. #7
    Membre Expert
    Inscrit en
    Août 2009
    Messages
    1 073
    Détails du profil
    Informations forums :
    Inscription : Août 2009
    Messages : 1 073
    Par défaut
    Citation Envoyé par Waldar Voir le message
    Je ne vois toujours pas comment mettre à jour une ligne qu'on ne trouve pas.
    Soit l'expression :

    MERGE INTO cible USING source ON (condition)

    J'ai 3 cas :
    1. Une ligne commune aux deux tables, avec la condition respectée : je fais en général un UPDATE.
    2. J'ai une ligne de source qui n'a pas de correspondance dans cible (au sens de "condition") : je fais en général un INSERT.
    3. Cas non traité par Oracle : j'ai une ligne de cible qui n'a pas de correspondance dans source (toujours au sens de "condition"). Et là, merlubreizh souhaiterait faire un UPDATE.

  8. #8
    Expert confirmé
    Avatar de StringBuilder
    Homme Profil pro
    Chef de projets
    Inscrit en
    Février 2010
    Messages
    4 197
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Rhône (Rhône Alpes)

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

    Informations forums :
    Inscription : Février 2010
    Messages : 4 197
    Billets dans le blog
    1
    Par défaut
    http://technet.microsoft.com/fr-fr/l.../bb510625.aspx

    On peut imaginer le scénario suivant :
    - Une table "client" (cli_id, cli_sigle, cli_nom, cli_naissance, commentaire)
    - Une table "changements" (cli_signel, cli_nom, cli_naissance)

    La table "client" est le référentiel client.
    La table "changements" est alimentée par une interface qui envoie des modifications sur les clients : ajouts, mises à jour.

    Contenu de la table "client" :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    cli_id      cli_sigle cli_nom                        cli_naissance commentaire
    ----------- --------- ------------------------------ ------------- ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    1           000001    Durant                         1980-12-28    
    2           000002    Client 2                       1970-01-15    
    3           000003    Dupuis                         1990-03-20    
    4           000004    Client 4                       1990-06-25    
     
    (4 row(s) affected)
    Table "changements" :
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    cli_sigle cli_nom                        cli_naissance
    --------- ------------------------------ -------------
    000002    Dupont                         NULL
    000005    Client 5                       1956-04-25
     
    (2 row(s) affected)

    Un merge :
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    merge client t
    using (select cli_sigle, cli_nom, cli_naissance from changements) s
    on s.cli_sigle = t.cli_sigle
    when matched then
    	update set t.cli_nom = coalesce(s.cli_nom, t.cli_nom), t.cli_naissance = coalesce(s.cli_naissance, t.cli_naissance), t.commentaire = t.commentaire + 'Mis à jour le ' + cast(getdate() as varchar)
    when not matched by source and t.cli_nom like 'Client %' then
    	update set t.commentaire = 'Non mis à jour le ' + cast(getdate() as varchar) + '\n'
    when not matched by target then
    	insert (cli_sigle, cli_nom, cli_naissance, commentaire) values (s.cli_sigle, s.cli_nom, s.cli_naissance, 'Ajouté le ' + cast(getdate() as varchar));
    => Quand on trouve le même sigle, on met à jour le nom et la date de naissance s'ils sont rempli
    => Quand on ne trouve pas dans la table TARGET, on ajoute le client
    => Quand on ne trouve pas dans la table SOURCE et que le client a le nom générique "Client x", on indique dans les commentaires qu'on n'a pas mis à jour la ligne

    Résultat :
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    cli_id      cli_sigle cli_nom                        cli_naissance commentaire
    ----------- --------- ------------------------------ ------------- ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    1           000001    Durant                         1980-12-28    
    2           000002    Dupont                         1970-01-15    Mis à jour le Sep 11 2012  3:16PMMis à jour le Sep 11 2012  3:19PM
    3           000003    Dupuis                         1990-03-20    
    4           000004    Client 4                       1990-06-25    Non mis à jour le Sep 11 2012  3:19PM\n
    5           000005    Client 5                       1956-04-25    Ajouté le Sep 11 2012  3:19PM
     
    (5 row(s) affected)

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

Discussions similaires

  1. Utilisation de l'instruction instanceof
    Par menzlitsh dans le forum Langage
    Réponses: 10
    Dernier message: 02/11/2009, 16h54
  2. Réponses: 4
    Dernier message: 07/01/2009, 17h34
  3. [XI] Utilisation de l'instruction IIF
    Par tatayoyo dans le forum SAP Crystal Reports
    Réponses: 8
    Dernier message: 28/03/2007, 14h20
  4. Utilisation de la fonction Merge
    Par MegaNam dans le forum Fortran
    Réponses: 2
    Dernier message: 26/03/2007, 13h49
  5. utilisation de la fonction Merge de sql
    Par freestyler dans le forum Langage SQL
    Réponses: 2
    Dernier message: 27/10/2006, 14h16

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