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

Requêtes PostgreSQL Discussion :

UPSERT (MySQL -> PostgreSQL)


Sujet :

Requêtes PostgreSQL

  1. #1
    Membre confirmé
    Homme Profil pro
    Inscrit en
    Juin 2011
    Messages
    445
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Juin 2011
    Messages : 445
    Points : 622
    Points
    622
    Par défaut UPSERT (MySQL -> PostgreSQL)
    Bonjour,

    J'ai cette requête ( MySQL) que j'aimerai écrire pour postgresql :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    INSERT INTO test7(idTest7,test7Long,test7Int,test7Float,test7CharArray,test7Timestamp,test7Date) 
    VALUES (72063769328484353,0,1,0.0,'','1970-01-01 00:00:00.0','1970-01-01'),
           (72063769328484354,0,2,0.0,'','1970-01-01 00:00:00.0','1970-01-01')
    ON DUPLICATE KEY UPDATE 
    	test7Long=VALUES(test7Long),
    	test7Int=VALUES(test7Int),
    	test7Float=VALUES(test7Float),
    	test7CharArray=VALUES(test7CharArray),
    	test7Timestamp=VALUES(test7Timestamp),
    	test7Date=VALUES(test7Date)

    En cherchant un peu sur le net, j'ai trouvé cette façon de faire :
    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
    WITH new_values (idTest7,test7Long,test7Int,test7Float,test7CharArray,test7Timestamp,test7Date) AS (
      VALUES 
        (72063769328484353,0,3,0.0,'',CAST ('1970-01-01 00:00:00.0' AS timestamp),CAST ('1970-01-01' AS DATE)),
        (72063769328484354,0,2,0.0,'',CAST ('1970-01-01 00:00:00.0' AS timestamp),CAST ('1970-01-01' AS DATE)) 
    ),
    upsert AS
    ( 
        UPDATE test7 
            SET test7Long = new_values.test7Long,
                test7Int = new_values.test7Int,
                test7Float = new_values.test7Float,
                test7CharArray = new_values.test7CharArray,
                test7Timestamp =new_values.test7Timestamp,
                test7Date = new_values.test7Date
        FROM new_values
        WHERE test7.idTest7 = new_values.idTest7
        RETURNING test7.*
    )
    INSERT INTO test7 (idTest7,test7Long,test7Int,test7Float,test7CharArray,test7Timestamp,test7Date)
    SELECT idTest7,test7Long,test7Int,test7Float,test7CharArray,test7Timestamp,test7Date
    FROM new_values
    WHERE NOT EXISTS (SELECT 1 
                      FROM upsert
                      WHERE upsert.idTest7 = new_values.idTest7)
    Est-ce une bonne façon de faire ?
    Il y a t'il une meilleure façon de faire ?

    Merci de votre aide.

  2. #2
    Expert confirmé
    Homme Profil pro
    Inscrit en
    Mai 2002
    Messages
    3 173
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Rhône (Rhône Alpes)

    Informations forums :
    Inscription : Mai 2002
    Messages : 3 173
    Points : 5 345
    Points
    5 345
    Par défaut
    Bonjour,


    Ce que vous tentez de faire est un MERGE.
    Non supporté par Postgresql.

    Donc c'est bien un upsert qu'il va falloir utiliser. (ou 2 requêtes ..)

  3. #3
    Membre confirmé
    Homme Profil pro
    Inscrit en
    Juin 2011
    Messages
    445
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Juin 2011
    Messages : 445
    Points : 622
    Points
    622
    Par défaut
    Citation Envoyé par punkoff Voir le message
    Ce que vous tentez de faire est un MERGE.
    MERGE, je l'ai utilisé avec plus ou moins de réussite sur Oracle :
    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 test7 target
      USING (
        SELECT 72063788739723265 AS idTest7,0 AS test7Long,2 AS test7Int,0.0 AS test7Float,'' AS test7CharArray,CAST('01/01/1970 00:00:00,0' AS timestamp) AS test7Timestamp,CAST('01/01/1970' AS date) AS test7Date FROM DUAL
        UNION
        SELECT 72063788739723267 AS idTest7,0 AS test7Long,2 AS test7Int,0.0 AS test7Float,'' AS test7CharArray,CAST('01/01/1970 00:00:00,0' AS timestamp) AS test7Timestamp,CAST('01/01/1970' AS date) AS test7Date FROM DUAL
      )new_values
      ON (new_values.idTest7 = target.idTest7)
      WHEN  MATCHED
      THEN UPDATE SET   
    			target.test7Long = new_values.test7Long,
    			target.test7Int = new_values.test7Int,
    			target.test7Float = new_values.test7Float,
    			target.test7CharArray = new_values.test7CharArray,
    			target.test7Timestamp = new_values.test7Timestamp,
    			target.test7Date = new_values.test7Date
      WHEN NOT MATCHED
      THEN
          INSERT (idTest7,test7Long,test7Int,target.test7Float,test7CharArray,test7Timestamp,test7Date)
          VALUES (new_values.idTest7,new_values.test7Long,new_values.test7Int,new_values.test7Float,new_values.test7CharArray,new_values.test7Timestamp,new_values.test7Date);
    Citation Envoyé par punkoff Voir le message
    Donc c'est bien un upsert qu'il va falloir utiliser.
    Dois-je comprendre qu'il y a une seule façon de faire un upsert ?

  4. #4
    Expert confirmé
    Homme Profil pro
    Inscrit en
    Mai 2002
    Messages
    3 173
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Rhône (Rhône Alpes)

    Informations forums :
    Inscription : Mai 2002
    Messages : 3 173
    Points : 5 345
    Points
    5 345
    Par défaut
    Cette fonctionnalité est très mal documentée et l'utilisation d'une CTE pour arriver à faire un upsert me semble plus d'une solution de contournement qu'autre chose.


    Bref, pour l'instant cette solution marche, mais c'est assez exotique.


    J'utiliserai plutôt 2 requêtes que ce truc là personnellement.

Discussions similaires

  1. Choisir Mysql ou PostGreSQL ?
    Par ohan dans le forum Décisions SGBD
    Réponses: 97
    Dernier message: 18/04/2011, 16h42
  2. conversion mysql vers postgresql
    Par backus dans le forum PostgreSQL
    Réponses: 3
    Dernier message: 04/07/2005, 18h42
  3. Migrer de MySQL vers PostgreSQL
    Par Acti dans le forum PostgreSQL
    Réponses: 9
    Dernier message: 25/02/2005, 14h20
  4. Mysql ou postgresql
    Par agro dans le forum Décisions SGBD
    Réponses: 10
    Dernier message: 22/10/2003, 13h01
  5. Réponses: 4
    Dernier message: 28/09/2002, 00h00

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