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

Développement SQL Server Discussion :

Toujours des problèmes avec MERGE [2008R2]


Sujet :

Développement SQL Server

  1. #21
    Expert éminent
    Avatar de Lyche
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Janvier 2007
    Messages
    2 523
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Administrateur de base de données

    Informations forums :
    Inscription : Janvier 2007
    Messages : 2 523
    Points : 6 775
    Points
    6 775
    Billets dans le blog
    4
    Par défaut
    Je ne parlais pas de plus hein Juste une petite note d'une ligne avant le merge pour expliquer le principe d'encapsulation et zou!

    Et oui, il est clair qu'à moins d'être particulièrement sale dans ses déclarations de variable, ce n'est pas réellement compliqué à comprendre comme code
    Rejoignez la communauté du chat et partagez vos connaissances ou vos questions avec nous

    Mon Tutoriel pour apprendre les Agregations
    Consultez mon Blog SQL destiné aux débutants

    Pensez à FAQ SQL Server Ainsi qu'aux Cours et Tuto SQL Server

  2. #22
    Expert confirmé
    Avatar de Kropernic
    Homme Profil pro
    Analyste / Programmeur / DBA
    Inscrit en
    Juillet 2006
    Messages
    3 932
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : Belgique

    Informations professionnelles :
    Activité : Analyste / Programmeur / DBA
    Secteur : Distribution

    Informations forums :
    Inscription : Juillet 2006
    Messages : 3 932
    Points : 4 239
    Points
    4 239
    Par défaut
    Citation Envoyé par Lyche Voir le message
    Je ne parlais pas de plus hein Juste une petite note d'une ligne avant le merge pour expliquer le principe d'encapsulation et zou!

    Et oui, il est clair qu'à moins d'être particulièrement sale dans ses déclarations de variable, ce n'est pas réellement compliqué à comprendre comme code
    On est bien d'accord. Mais vu que mes collègues ne se tiennent pas au courant des avancées "technologiques", aucune chance qu'il sache comment fonctionne l'instruction merge.

    Voici à quoi ressemble un bout de la procédure stockée sur laquelle je bosse actuellement. Perso, ça me semble assez clair. Si mon collègue direct doit aller dedans, je suis certain qu'il va patauger et que, s'il faut vraiment corriger un truc, réécrira le code avec des insert/update/delete.
    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
        --MAJ DES GROUPES DE SAISONS
        DECLARE @INSERTED TABLE (
            SOURCE_ID INT,
            TARGET_ID INT);
     
        INSERT INTO @INSERTED
        SELECT SOURCE_ID, TARGET_ID    
        FROM    (
                --MERGING DES GROUPES DE SAISONS
                MERGE    S_PROMO.T_SEASON_GROUP_SGP AS TARGET
                USING    (SELECT DISTINCT LS.SGP_ID, LS.PEO_VALUE, LS.ISNEW, PEO.PEO_ID
                        FROM @LIST_SEASONS LS 
                                INNER JOIN S_PROMO.T_PERCENTAGE_OWN_PEO PEO
                                    ON    PEO.DTO_ID = @DTO_ID
                                    AND PEO.PEO_PERCENTAGE = LS.PEO_VALUE) AS SOURCE (SGP_ID, PEO_VALUE, ISNEW, PEO_ID)
                    ON    (TARGET.SGP_ID = SOURCE.SGP_ID AND SOURCE.ISNEW = 0)
                WHEN MATCHED THEN
                    UPDATE SET PEO_ID = SOURCE.PEO_ID
                WHEN NOT MATCHED THEN
                    INSERT (PEO_ID) VALUES(SOURCE.PEO_ID) 
                WHEN NOT MATCHED BY SOURCE THEN
                    DELETE
                OUTPUT INSERTED.SGP_ID, SOURCE.SGP_ID, $ACTION) AS RqMERGE(TARGET_ID, SOURCE_ID, ACTIONS)
        WHERE    ACTIONS = 'INSERTED';
     
        --MERGING DES COMMENTAIRES DES GROUPES DE SAISONS
        MERGE    S_PROMO.T_SGP_COMMENT_SGC AS TARGET
        USING    (SELECT DISTINCT INS.TARGET_ID, LS.COMMENT
                FROM    @LIST_SEASONS LS
                            INNER JOIN @INSERTED INS
                                ON    LS.SGP_ID = INS.SOURCE_ID
                WHERE    LS.ISNEW = 1
                UNION
                SELECT    DISTINCT LS.SGP_ID, LS.COMMENT
                FROM    @LIST_SEASONS LS
                WHERE    LS.ISNEW = 0) AS SOURCE (SGP_ID, COMMENT)
            ON    TARGET.SGP_ID = SOURCE.SGP_ID
        WHEN MATCHED THEN
            UPDATE SET SGC_COMMENT = SOURCE.COMMENT
        WHEN NOT MATCHED THEN    
            INSERT(SGP_ID, SGC_COMMENT) VALUES (SOURCE.SGP_ID, SOURCE.COMMENT);
     
        --MERGING DES REMARQUES DES GROUPES DE SAISONS
        MERGE    S_PROMO.T_SGP_NOTE_SGN AS TARGET
        USING    (SELECT DISTINCT INS.TARGET_ID, LS.NOTE
                FROM    @LIST_SEASONS LS
                            INNER JOIN @INSERTED INS
                                ON    LS.SGP_ID = INS.SOURCE_ID
                WHERE    LS.ISNEW = 1
                UNION
                SELECT    DISTINCT LS.SGP_ID, LS.NOTE
                FROM    @LIST_SEASONS LS
                WHERE    LS.ISNEW = 0) AS SOURCE (SGP_ID, NOTE)
            ON    TARGET.SGP_ID = SOURCE.SGP_ID
        WHEN MATCHED THEN
            UPDATE SET SGN_NOTE = SOURCE.NOTE
        WHEN NOT MATCHED THEN    
            INSERT(SGP_ID, SGN_NOTE) VALUES (SOURCE.SGP_ID, SOURCE.NOTE);
    Kropernic

  3. #23
    Expert éminent
    Avatar de Lyche
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Janvier 2007
    Messages
    2 523
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Administrateur de base de données

    Informations forums :
    Inscription : Janvier 2007
    Messages : 2 523
    Points : 6 775
    Points
    6 775
    Billets dans le blog
    4
    Par défaut
    et en plus ton code est sexy
    Rejoignez la communauté du chat et partagez vos connaissances ou vos questions avec nous

    Mon Tutoriel pour apprendre les Agregations
    Consultez mon Blog SQL destiné aux débutants

    Pensez à FAQ SQL Server Ainsi qu'aux Cours et Tuto SQL Server

  4. #24
    Expert confirmé
    Avatar de Kropernic
    Homme Profil pro
    Analyste / Programmeur / DBA
    Inscrit en
    Juillet 2006
    Messages
    3 932
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : Belgique

    Informations professionnelles :
    Activité : Analyste / Programmeur / DBA
    Secteur : Distribution

    Informations forums :
    Inscription : Juillet 2006
    Messages : 3 932
    Points : 4 239
    Points
    4 239
    Par défaut
    Et j'ai même réussi à y glisser une petite référence à Stargate-SG1.

    Mais bon, je dois avouer que ce n'est pas totalement fait exprès.
    Kropernic

  5. #25
    Modérateur

    Profil pro
    dba
    Inscrit en
    Janvier 2010
    Messages
    5 643
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : dba

    Informations forums :
    Inscription : Janvier 2010
    Messages : 5 643
    Points : 13 092
    Points
    13 092
    Par défaut
    Je me demande du coup si le filtre sur les lignes insérée uniquement est si intéressant.
    Car si la table @INSERTED contenait également les "vrais" identifiants des lignes mises à jour, ça simplifierai l'écriture des requetres MERGE suivantes, car alors par exemple
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
     USING    (SELECT DISTINCT INS.TARGET_ID, LS.NOTE
                FROM    @LIST_SEASONS LS
                            INNER JOIN @INSERTED INS
                                ON    LS.SGP_ID = INS.SOURCE_ID
                WHERE    LS.ISNEW = 1
                UNION
                SELECT    DISTINCT LS.SGP_ID, LS.NOTE
                FROM    @LIST_SEASONS LS
                WHERE    LS.ISNEW = 0) AS SOURCE (SGP_ID, NOTE)
    deviendrait simplement (et sauf erreur de ma part )
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
     USING    (SELECT DISTINCT INS.TARGET_ID, LS.NOTE
                FROM    @LIST_SEASONS LS
                            INNER JOIN @INSERTED INS
                                ON    LS.SGP_ID = INS.SOURCE_ID
                ) AS SOURCE (SGP_ID, NOTE)
    a voir l'impact sur les performances...

  6. #26
    Expert éminent
    Avatar de Lyche
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Janvier 2007
    Messages
    2 523
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Administrateur de base de données

    Informations forums :
    Inscription : Janvier 2007
    Messages : 2 523
    Points : 6 775
    Points
    6 775
    Billets dans le blog
    4
    Par défaut
    Lorsque tu fais un UPDATE, tu as une action de suppression et une action d'insertion qui se produit pour la ligne mise à jour.

    Dans la table Inserted, tu auras les informations nouvellement insérées, et pour $Action "UPDATE", dans le même temps, tu as dans la table DELETED les informations contenues avant l'exécution du MERGE. Il est important de filtrer si le besoin est d'identifier les lignes nouvellement entrantes dans la base.

    Cordialement,
    Lyche
    Rejoignez la communauté du chat et partagez vos connaissances ou vos questions avec nous

    Mon Tutoriel pour apprendre les Agregations
    Consultez mon Blog SQL destiné aux débutants

    Pensez à FAQ SQL Server Ainsi qu'aux Cours et Tuto SQL Server

  7. #27
    Expert confirmé
    Avatar de Kropernic
    Homme Profil pro
    Analyste / Programmeur / DBA
    Inscrit en
    Juillet 2006
    Messages
    3 932
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : Belgique

    Informations professionnelles :
    Activité : Analyste / Programmeur / DBA
    Secteur : Distribution

    Informations forums :
    Inscription : Juillet 2006
    Messages : 3 932
    Points : 4 239
    Points
    4 239
    Par défaut
    Citation Envoyé par Lyche Voir le message
    Lorsque tu fais un UPDATE, tu as une action de suppression et une action d'insertion qui se produit pour la ligne mise à jour.

    Dans la table Inserted, tu auras les informations nouvellement insérées, et pour $Action "UPDATE", dans le même temps, tu as dans la table DELETED les informations contenues avant l'exécution du MERGE. Il est important de filtrer si le besoin est d'identifier les lignes nouvellement entrantes dans la base.

    Cordialement,
    Lyche
    Oui oui mais en filtrant sur l'action inserted, je ne vais quand même pas me manger les valeurs de inserted pour les actions update j'espère. Non ?
    Kropernic

  8. #28
    Expert éminent
    Avatar de Lyche
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Janvier 2007
    Messages
    2 523
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Administrateur de base de données

    Informations forums :
    Inscription : Janvier 2007
    Messages : 2 523
    Points : 6 775
    Points
    6 775
    Billets dans le blog
    4
    Par défaut
    Non, comme je t'expliquais au dessus, (peut-être mal), les lignes dans la table INSERTED qui proviennent de l'action UPDATE sont marqué à UPDATE. L'action global qui se produit lors d'un UPDATE est un DELETE/INSERT d'où la présence des informations dans les 2 tables de session. Mais, l'actions est bien un UPDATE

    Au pire, essaye, reitre le filtre et regarde les informations qui remontent en rajouter une colonne Action dans ta table
    Rejoignez la communauté du chat et partagez vos connaissances ou vos questions avec nous

    Mon Tutoriel pour apprendre les Agregations
    Consultez mon Blog SQL destiné aux débutants

    Pensez à FAQ SQL Server Ainsi qu'aux Cours et Tuto SQL Server

  9. #29
    Expert confirmé
    Avatar de Kropernic
    Homme Profil pro
    Analyste / Programmeur / DBA
    Inscrit en
    Juillet 2006
    Messages
    3 932
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : Belgique

    Informations professionnelles :
    Activité : Analyste / Programmeur / DBA
    Secteur : Distribution

    Informations forums :
    Inscription : Juillet 2006
    Messages : 3 932
    Points : 4 239
    Points
    4 239
    Par défaut
    Citation Envoyé par aieeeuuuuu Voir le message
    Je me demande du coup si le filtre sur les lignes insérée uniquement est si intéressant.
    Car si la table @INSERTED contenait également les "vrais" identifiants des lignes mises à jour, ça simplifierai l'écriture des requetres MERGE suivantes, car alors par exemple
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
     USING    (SELECT DISTINCT INS.TARGET_ID, LS.NOTE
                FROM    @LIST_SEASONS LS
                            INNER JOIN @INSERTED INS
                                ON    LS.SGP_ID = INS.SOURCE_ID
                WHERE    LS.ISNEW = 1
                UNION
                SELECT    DISTINCT LS.SGP_ID, LS.NOTE
                FROM    @LIST_SEASONS LS
                WHERE    LS.ISNEW = 0) AS SOURCE (SGP_ID, NOTE)
    deviendrait simplement (et sauf erreur de ma part )
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
     USING    (SELECT DISTINCT INS.TARGET_ID, LS.NOTE
                FROM    @LIST_SEASONS LS
                            INNER JOIN @INSERTED INS
                                ON    LS.SGP_ID = INS.SOURCE_ID
                ) AS SOURCE (SGP_ID, NOTE)
    a voir l'impact sur les performances...
    Va falloir que j'analyse ça en détail ^^. Mais y a quelque chose à exploiter je pense.
    Kropernic

  10. #30
    Modérateur

    Profil pro
    dba
    Inscrit en
    Janvier 2010
    Messages
    5 643
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : dba

    Informations forums :
    Inscription : Janvier 2010
    Messages : 5 643
    Points : 13 092
    Points
    13 092
    Par défaut
    Citation Envoyé par Lyche Voir le message
    Il est important de filtrer si le besoin est d'identifier les lignes nouvellement entrantes dans la base.
    Il me semble justement que le besoin est de récupérer les lignes ajoutées ou modifiées (d'où le UNION dans les requêtes suivante, pour récupérer les nouvelles lignes dans le premier select, et les lignes modifiées dans le second)

    Je dirai même qu'il pourrait être utile, lors du premier OUTPUT, de récupérer LS.Note dans @INSERTED afin de ne plus avoir besoin de la jointure avec @LIST_SEASONS...

  11. #31
    Expert confirmé
    Avatar de Kropernic
    Homme Profil pro
    Analyste / Programmeur / DBA
    Inscrit en
    Juillet 2006
    Messages
    3 932
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : Belgique

    Informations professionnelles :
    Activité : Analyste / Programmeur / DBA
    Secteur : Distribution

    Informations forums :
    Inscription : Juillet 2006
    Messages : 3 932
    Points : 4 239
    Points
    4 239
    Par défaut
    Citation Envoyé par aieeeuuuuu Voir le message
    Il me semble justement que le besoin est de récupérer les lignes ajoutées ou modifiées (d'où le UNION dans les requêtes suivante, pour récupérer les nouvelles lignes dans le premier select, et les lignes modifiées dans le second)

    Je dirai même qu'il pourrait être utile, lors du premier OUTPUT, de récupérer LS.Note dans @INSERTED afin de ne plus avoir besoin de la jointure avec @LIST_SEASONS...
    Je vais regarder à tout ça mais j'ai un autre problème plus prioritaire qui m'est tombé dessus ce matin. Mais déjà un grand merci pour toutes ces propositions et le temps que vous m'avez tous les deux accordés.
    Kropernic

+ Répondre à la discussion
Cette discussion est résolue.
Page 2 sur 2 PremièrePremière 12

Discussions similaires

  1. Encore des problèmes avec le BDE
    Par Flint dans le forum C++Builder
    Réponses: 19
    Dernier message: 31/12/2007, 23h26
  2. j'ai des problèmes avec un virus
    Par beencss dans le forum Sécurité
    Réponses: 4
    Dernier message: 02/02/2007, 13h56
  3. Toujours un problème avec Timer
    Par adidas40 dans le forum VB 6 et antérieur
    Réponses: 5
    Dernier message: 10/10/2006, 11h04
  4. SQL server et toujours des problèmes de dates ...
    Par constantin dans le forum MS SQL Server
    Réponses: 10
    Dernier message: 28/10/2005, 12h19
  5. toujours des problemes avec ce DROP
    Par Missvan dans le forum PostgreSQL
    Réponses: 2
    Dernier message: 18/02/2004, 08h43

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