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

Langage SQL Discussion :

Missing keyword with MERGE INTO


Sujet :

Langage SQL

  1. #1
    Nouveau membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2017
    Messages
    42
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2017
    Messages : 42
    Points : 28
    Points
    28
    Par défaut Missing keyword with MERGE INTO
    Bonjour,

    voilà j'ai une requête très simple mais je n'arrive pas à corriger une erreur...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    MERGE INTO ATEST
    USING (SELECT * FROM BTEST)
    ON (ATEST.id = BTEST.id) 
    WHEN MATCHED  THEN 
         (UPDATE 
            SET (couleur,forme) = (SELECT BTEST.couleur, BTEST.forme FROM BTEST WHERE ATEST.id = BTEST.id) 
            WHERE EXISTS (SELECT 1 FROM BTEST WHERE BTEST.id = ATEST.id ))
    WHEN NOT MATCHED THEN 
        INSERT INTO ATEST SELECT * FROM BTEST MINUS SELECT * FROM ATEST
    L'erreur est sur sql developer :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    Erreur à la ligne de commande: 5 Colonne: 6
    Rapport d'erreur -
    Erreur SQL : ORA-00905: mot-clé absent
    00905. 00000 -  "missing keyword"
    *Cause:    
    *Action:
    Merci bcp!

  2. #2
    Modérateur
    Avatar de al1_24
    Homme Profil pro
    Retraité
    Inscrit en
    Mai 2002
    Messages
    9 099
    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 099
    Points : 28 390
    Points
    28 390
    Par défaut
    Pourquoi se compliquer alors que c'est si simple ?
    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
    MERGE INTO  ATEST
        USING   BTEST
            ON  (ATEST.id = BTEST.id) 
    WHEN MATCHED  THEN 
        UPDATE 
            SET     ATEST.couleur   = BTEST.couleur
                ,   ATEST.forme     = BTEST.forme
    WHEN NOT MATCHED THEN 
        INSERT  
            (   id
            ,   couleur
            ,   forme
            )
        VALUES  
            (   BTEST.id
            ,   BTEST.couleur
            ,   BTEST.forme
            )
    ;
    MERGE s'occupe tout seul de faire correspondre les lignes sur la clé de jointure (ON ...) et de séparer les nouvelles lignes de celles qui sont déjà présentes. Pas besoin d'en rajouter une couche.

  3. #3
    Nouveau membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2017
    Messages
    42
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2017
    Messages : 42
    Points : 28
    Points
    28
    Par défaut
    Ah oui effectivement, merci bcp!

  4. #4
    Nouveau membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2017
    Messages
    42
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2017
    Messages : 42
    Points : 28
    Points
    28
    Par défaut
    En fait c'est vrai que ta solution est simple mais du coup cela change le comportement de la requête car les données en trop dans ATEST ne sont plus supprimés quand on update via BTEST.

    Par exemple si il y a 10 lignes dans ATEST et 5 dans BTEST, après la requête il n'y aura pas 5 lignes dans ATEST donc la mise à jour n'est pas bonne.

    J'ai essayé avec :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
     
    MERGE INTO .ATEST 
     USING BTEST 
     ON (ATEST.ID = .BTEST.ID ) 
     WHEN MATCHED THEN 
    UPDATE 
    SET ATEST.COULEUR = BTEST.COULEUR, ATEST.FORME = BTEST.FORME
     WHEN NOT MATCHED THEN
     INSERT (ID,COULEUR,FORME) 
     VALUES (BTEST.ID, BTEST.COULEUR, BTEST.FORME)
     WHEN NOT MATCHED BY SOURCE THEN
         DELETE
    Mais j'ai tjrs des erreurs étranges, très chiantes à corriger pour un néophyte :'(

  5. #5
    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
    Si vous ne voulez pas supprimer les lignes dans la cible, il suffit de ne pas lui dire de supprimer les lignes dans la cible !

    enlevez le
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    WHEN NOT MATCHED BY SOURCE THEN
         DELETE

  6. #6
    Nouveau membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2017
    Messages
    42
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2017
    Messages : 42
    Points : 28
    Points
    28
    Par défaut
    Si, justement, j'aimerai supprimer les lignes dans la cible mais c'est cela que je n'arrive pas à faire fonctionner.

  7. #7
    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
    alors précisez les erreurs que vous obtenez, ou décrivez le comportement qui vous semble anormal... car je ne vois pas d'erreur dans la requête

  8. #8
    Nouveau membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2017
    Messages
    42
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2017
    Messages : 42
    Points : 28
    Points
    28
    Par défaut
    Alors j'ai presque trouvé la solution :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
     
    MERGE INTO ATEST 
     USING BTEST
     ON (ATEST.ID = BTEST.ID ) 
     WHEN MATCHED THEN 
    UPDATE 
    SET ATEST.COULEUR = BTEST.COULEUR, ATEST.FORME = BTEST.FORME
    DELETE WHERE  not exists (select * from ATEST)
     WHEN NOT MATCHED THEN
     INSERT (ID,COULEUR,FORME) 
     VALUES (BTEST.ID, BTEST.COULEUR, BTEST.FORME);
    La requête s’exécute mais le comportement n'est pas celui que je veux.

    Je m'explique :

    Dans ma table BTEST j'ai :

    Nom : BTEST.PNG
Affichages : 217
Taille : 2,2 Ko

    Je fais la requete et ma classe ATEST change :

    Nom : ATEST.PNG
Affichages : 226
Taille : 3,5 Ko

    Sauf que la ligne avec l'id 1 n'est pas supprimé et elle devrait car elle n'est pas dans BTEST (qui est la source donc)

  9. #9
    Membre expérimenté
    Homme Profil pro
    Architecte de base de données
    Inscrit en
    Septembre 2016
    Messages
    776
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 57
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Architecte de base de données
    Secteur : Conseil

    Informations forums :
    Inscription : Septembre 2016
    Messages : 776
    Points : 1 488
    Points
    1 488
    Par défaut
    Citation Envoyé par Fellowes Voir le message
    Je fais la requete et ma classe ATEST change :
    Sauf que la ligne avec l'id 1 n'est pas supprimé et elle devrait car elle n'est pas dans BTEST (qui est la source donc)
    Bonsoir,
    pas compris si la suppression devait avoir lieu sur Btest ou sur Atest.

    Merci de donner un exemple avec les valeurs avant (BTEST et ATEST) et les valeurs souhaitées après exécution (ATEST et BTEST)

  10. #10
    Nouveau membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2017
    Messages
    42
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2017
    Messages : 42
    Points : 28
    Points
    28
    Par défaut
    Alors je vais faire de mon mieux pour expliquer :

    J'ai deux tables :

    ATEST
    ------------------------
    ID | Forme | Couleur |
    1----rond----rouge
    3----triangle---jaune

    BTEST
    ------------------------
    ID | Forme | Couleur |
    1---rond-----noir
    2---carre----bleu



    Quand j’exécute la requête je veux tout copier dans ATEST en prenant tout ce qu'il y a dans BTEST et en supprimant les lignes qui n'existent pas.
    On a donc après :


    ATEST
    ------------------------
    ID | Forme | Couleur |
    1----rond-----noir <------- Dans ATEST la ligne 1 est passé de rond rouge à rond noir
    2----carre----bleu <------- La ligne avec ID 3 est supprimé car elle n'existe pas dans BTEST et la ligne avec ID est rajoutée donc on a les deux tables identiques

    BTEST
    ------------------------
    ID | Forme | Couleur |
    1----rond----noir
    2---carre----bleu


    Voila, j’espère avoir été plus limpide :/ dsl pour le manque de cohérence dans mes propos

  11. #11
    Modérateur
    Avatar de al1_24
    Homme Profil pro
    Retraité
    Inscrit en
    Mai 2002
    Messages
    9 099
    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 099
    Points : 28 390
    Points
    28 390
    Par défaut
    Pour répondre à ton exemple, il suffirait de faire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    delete from atest;
    insert into atest
    select * from btest;

  12. #12
    Expert confirmé
    Profil pro
    Inscrit en
    Août 2008
    Messages
    2 950
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2008
    Messages : 2 950
    Points : 5 849
    Points
    5 849
    Par défaut
    Il faut qu'il y ai un match, donc il faut les ID de ATEST dans la partie USING qui accepte les requêtes.
    Passer par un FULL OUTER JOIN dans la partie USING et supprimer les lignes quand BTEST.ID est NULL dans le FULL OUTER JOIN, quelque chose comme ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
      MERGE INTO ATEST 
      USING (selelct nvl(a.id, b.id) as u_id, a.id as id_dest, b.id as id_source, b.*
                from ATEST a 
                full join BTEST b on a.id = b.id
             ) u
      ON (ATEST.ID = u.u_ID ) 
      WHEN MATCHED THEN 
    UPDATE SET ATEST.COULEUR = BTEST.COULEUR
         , ATEST.FORME = BTEST.FORME
    DELETE WHERE u.id_source is null
      WHEN NOT MATCHED THEN
    INSERT (ID,COULEUR,FORME) 
    VALUES (BTEST.ID, BTEST.COULEUR, BTEST.FORME);
    Effectivement comme mentionné par Alain, vous pouvez peut être aussi simplement purger ATEST (potentiellement avec un TRUNCATE) et la recharger avec BTEST.

Discussions similaires

  1. Transcrire "Merge into"
    Par Ndrmar dans le forum SQL
    Réponses: 6
    Dernier message: 11/09/2008, 12h24
  2. SQL Merge into - delete ne marche pas
    Par Javotte dans le forum Langage SQL
    Réponses: 1
    Dernier message: 30/06/2008, 09h29
  3. Réponses: 4
    Dernier message: 11/10/2007, 08h51
  4. 9i : problème avec MERGE INTO
    Par Vld44 dans le forum SQL
    Réponses: 1
    Dernier message: 16/08/2007, 11h27
  5. [langage] [keyword] with et FireFox
    Par FremyCompany dans le forum Général JavaScript
    Réponses: 3
    Dernier message: 26/07/2006, 14h22

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