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 MySQL Discussion :

Prévoir les requêtes SQL et ne les exécuter que si pas d'erreurs


Sujet :

Requêtes MySQL

  1. #1
    Expert confirmé
    Avatar de laurentSc
    Homme Profil pro
    Webmaster débutant perpétuel !
    Inscrit en
    Octobre 2006
    Messages
    10 470
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Webmaster débutant perpétuel !
    Secteur : Industrie

    Informations forums :
    Inscription : Octobre 2006
    Messages : 10 470
    Points : 5 830
    Points
    5 830
    Billets dans le blog
    1
    Par défaut Prévoir les requêtes SQL et ne les exécuter que si pas d'erreurs
    Bonjour,

    j'ai un problème de conception.
    Je lis des données issues d'un fichier, puis je les stocke en bdd (donc des INSERT ou des UPDATE). Le souci est qu'il y a 5 tables, et que certains INSERT ou UPDATE dépendent de SELECT faits sur une autre table. Exemple :
    Code php : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    $sql_insert ="
    INSERT into `location` (location, country_key) VALUES (".$location.",".$country_key.");";
    J'ai simplifié le code pour vous montrer, mais c'est plus compliqué et les données sont en fait échappées.
    Dans cet exemple, on utilise la variable $country_key qu'on ne peut obtenir que grâce à cette requête :
    Code php : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    $sql_select ='
    SELECT country_key from `country` WHERE country = "'.$officecountry.'";';
    Cette requête ne retournera un résultat que si la table `country` a déjà été alimentée. Mais comme j'attends d'avoir fini de passer en revue l'ensemble des données et prévoir les INSERT ou UPDATE mais ne les exécuter que si aucune erreur détectée, le SELECT ci-dessus ne va rien retourner dont le INSERT va échouer. Donc, comment s'y prendre, SVP ?

  2. #2
    Expert confirmé
    Avatar de laurentSc
    Homme Profil pro
    Webmaster débutant perpétuel !
    Inscrit en
    Octobre 2006
    Messages
    10 470
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Webmaster débutant perpétuel !
    Secteur : Industrie

    Informations forums :
    Inscription : Octobre 2006
    Messages : 10 470
    Points : 5 830
    Points
    5 830
    Billets dans le blog
    1
    Par défaut
    En cherchant, j'ai trouvé la notion de variable SQL.

    Du coup, je pourrais faire un truc du genre :

    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    SELECT @country_key :=country_key  from `country` WHERE country = "France";
    INSERT into `location` (location, country_key) VALUES ("test",@country_key);

    Qu'en pensez-vous ?

    EDIT : cela permettrait de prévoir la requête d'insertion dans `location` avant d'avoir réalisé l'insertion dans `country`.

  3. #3
    Modérateur
    Avatar de al1_24
    Homme Profil pro
    Retraité
    Inscrit en
    Mai 2002
    Messages
    9 107
    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 107
    Points : 28 405
    Points
    28 405
    Par défaut
    Et pourquoi pas directement :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    INSERT INTO location
        (   location
        ,   country_key
        )
    SELECT  'test'
        ,   country_key
    FROM    country
    WHERE   country = 'France'
    ;

  4. #4
    Expert confirmé
    Avatar de laurentSc
    Homme Profil pro
    Webmaster débutant perpétuel !
    Inscrit en
    Octobre 2006
    Messages
    10 470
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Webmaster débutant perpétuel !
    Secteur : Industrie

    Informations forums :
    Inscription : Octobre 2006
    Messages : 10 470
    Points : 5 830
    Points
    5 830
    Billets dans le blog
    1
    Par défaut
    Cette requête fonctionne et est plus simple vu que le boulot est fait par une seule requête.

    Par contre, étant fort loin de l'expertise en SQL, quelques questions :

    - y a pas d'attribut VALUES dans la requête. Je suppose que la partie
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    SELECT  'test'
        ,   country_key
    FROM    country
    sert à attribuer les valeurs des colonnes, non ?

    - une des 2 valeurs est (choix pour faire simple) la chaîne de caractères 'test' mais elle n'a rien à voir avec la table country. Pourtant elle est dans le SELECT ...FROM country. Tu peux m'expliquer ?

  5. #5
    Expert confirmé
    Avatar de laurentSc
    Homme Profil pro
    Webmaster débutant perpétuel !
    Inscrit en
    Octobre 2006
    Messages
    10 470
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Webmaster débutant perpétuel !
    Secteur : Industrie

    Informations forums :
    Inscription : Octobre 2006
    Messages : 10 470
    Points : 5 830
    Points
    5 830
    Billets dans le blog
    1
    Par défaut
    Bonsoir,

    cherchant à comprendre la requête et en comparant avec un code voisin, je me pose la question de si y aurait pas moyen d'utiliser une jointure dans le genre :
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    INSERT `location` l (  l. location  ,   l.country_key)
    join `country` c ON c.country_key=l.country_key VALUES("test",c.country_key) where c.country="France"
    (c'est juste l'idée, vu que ce code n'est pas valable). Qu'en penses-tu ?

  6. #6
    Modérateur

    Avatar de CinePhil
    Homme Profil pro
    Ingénieur d'études en informatique
    Inscrit en
    Août 2006
    Messages
    16 801
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur d'études en informatique
    Secteur : Enseignement

    Informations forums :
    Inscription : Août 2006
    Messages : 16 801
    Points : 34 063
    Points
    34 063
    Billets dans le blog
    14
    Par défaut
    Comme vous programmez en PHP, je me demande si vous ne vous compliquez pas la vie dans l'exemple donné.

    J'imagine que les données viennent d'un formulaire qui comprend une liste déroulante des pays... alimentée par la table des pays, non ?

    Donc si votre liste déroulante est construite avec l'identifiant du pays en valeur de chaque option, vous récupérez directement l'identifiant du pays et pas besoin de vérifier qu'il existe déjà.

    Sinon, sauf erreur, on ne peut pas faire de JOIN dans un INSERT. La solution INSERT SELECT par contre fonctionne.

  7. #7
    Expert confirmé
    Avatar de laurentSc
    Homme Profil pro
    Webmaster débutant perpétuel !
    Inscrit en
    Octobre 2006
    Messages
    10 470
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Webmaster débutant perpétuel !
    Secteur : Industrie

    Informations forums :
    Inscription : Octobre 2006
    Messages : 10 470
    Points : 5 830
    Points
    5 830
    Billets dans le blog
    1
    Par défaut
    Merci de m'avoir répondu.

    En fait; l'origine des données est différente : l'utilisateur renseigne ailleurs une autre bdd, puis j'en récupère un export sous forme de fichier CSV. Donc, y a probablement une liste déroulante avec les pays...mais ailleurs.

    Merci pour l'info de l'impossibilité de jointure dans un INSERT.

    Pourriez-vous répondre aux 2 questions que j'ai posées dans le post #4 ?

  8. #8
    Modérateur

    Avatar de CinePhil
    Homme Profil pro
    Ingénieur d'études en informatique
    Inscrit en
    Août 2006
    Messages
    16 801
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur d'études en informatique
    Secteur : Enseignement

    Informations forums :
    Inscription : Août 2006
    Messages : 16 801
    Points : 34 063
    Points
    34 063
    Billets dans le blog
    14
    Par défaut
    - y a pas d'attribut VALUES dans la requête. Je suppose que la partie SELECT... sert à attribuer les valeurs des colonnes, non ?
    Oui.

    On peut faire ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    INSERT INTO latable (les, colonnes)
    SELECT une_colonne, une_autre_colonne
    FROM une_autre_table
    WHERE condition
    Et on peut aussi faire ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    INSERT INTO latable (les, colonnes)
    SELECT 'une_valeur', une_colonne
    FROM une_autre_table

  9. #9
    Expert éminent sénior Avatar de Artemus24
    Homme Profil pro
    Agent secret au service du président Ulysses S. Grant !
    Inscrit en
    Février 2011
    Messages
    6 464
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Agent secret au service du président Ulysses S. Grant !
    Secteur : Finance

    Informations forums :
    Inscription : Février 2011
    Messages : 6 464
    Points : 19 453
    Points
    19 453
    Par défaut
    Salut à tous.

    Citation Envoyé par LaurentSC
    Le souci est qu'il y a 5 tables, et que certains INSERT ou UPDATE dépendent de SELECT faits sur une autre table.
    Si vous lisez des données depuis un fichier ".csv", le mieux est de les stocker dans une table de travail.
    L'organisation des données n'étant pas la même, vous devez à partir de votre table de travail, extraire puis mettre en forme vos données afin de les répartire judiciusement dans vos tables définitives.
    J'entends pas là, éviter la répétition d'un même donnée, comme c'est le cas dans un fichier plat.
    Ne pas oublier que MySql est un SGBD relationnel.

    Si l'insertion ou la mise à jour dépendent d'un select, en quoi cela pose un problème ?
    Sur ce point, vous n'êtes pas clair car je ne comprends pas la nature de votre dépendance.

    Si elle concerne la présnce ou l'absence d'une données, il suffit la clause "where exists ..." ou "where not exists ..." dans un select.
    Et dans l'insert, vous faites référence à un select, c'est-à-dire à l'extraction de vos donnés.

    Je préfère qu vous soyez plus explicite sur un exemple, avec un jeu d'essai.

    Citation Envoyé par CinePhil
    Sinon, sauf erreur, on ne peut pas faire de JOIN dans un INSERT.
    Pour s'en rendre compte, il suffit de consulter la syntaxe du INSERT sous MySql :
    --> https://dev.mysql.com/doc/refman/8.0/en/insert.html

    Il n'y a pas de jointure directement appliquée sur un insert (en dehors de tout select).

    Citation Envoyé par CinePhil
    La solution INSERT SELECT par contre fonctionne.
    Oui, la solution est de passer par le "insert ... select ... on duplicate key update ...".

    @+

  10. #10
    Expert confirmé
    Avatar de laurentSc
    Homme Profil pro
    Webmaster débutant perpétuel !
    Inscrit en
    Octobre 2006
    Messages
    10 470
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Webmaster débutant perpétuel !
    Secteur : Industrie

    Informations forums :
    Inscription : Octobre 2006
    Messages : 10 470
    Points : 5 830
    Points
    5 830
    Billets dans le blog
    1
    Par défaut
    Désolé de ne répondre que maintenant...

    Tout d'abord, je vois pas l'intérêt de passer par une table de travail....

    Le souci que j'évoque de faire un insert dans une table qui dépend d'un select sur une autre table était juste que ça faisait 2 requêtes SQL mais depuis la réponse de Al1_24 au post #3, je sais le faire en une seule requête (c'est super).

    Petit exemple :

    j'ai une table country : country_key , country
    1    France
    2    Allemagne
    etc
    
    et une table location : location_key , location , country_key
    1   site_a_berlin      2
    2   site_a_angouleme   1
    etc
    Pour faire un INSERT dans la table location , avant, je ne savais le faire qu'avec les 2 requêtes du post #1, mais depuis le post #3, je peux le faire en une seule requête.


    Oui, la solution est de passer par le "insert ... select ... on duplicate key update ...".
    Le problème avec ce type de requête est que je ne saurai pas si on a fait un insert ou un update et je souhaite compter le nombre de ces requêtes.

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

Discussions similaires

  1. [MySQL] Requête SQL INSERT ne s'exécute pas
    Par xnooztv1 dans le forum PHP & Base de données
    Réponses: 3
    Dernier message: 26/05/2019, 14h21
  2. Erreur d'exécution 91 -> mais pas d'erreur en pas à pas détaillé
    Par Azoura-_-Flav dans le forum Macros et VBA Excel
    Réponses: 4
    Dernier message: 12/04/2018, 10h40
  3. Requête SQL très longue à s'exécuter
    Par dreamcat1 dans le forum SQL
    Réponses: 10
    Dernier message: 22/03/2010, 11h44
  4. [SQL] Requête sql où la condition where ne sert pas
    Par gRaNdLeMuRieN dans le forum PHP & Base de données
    Réponses: 3
    Dernier message: 16/05/2007, 09h26
  5. Réponses: 2
    Dernier message: 04/03/2006, 10h47

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