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

PHP & Base de données Discussion :

Requêtes préparées (PDO) avec données trop volumineuses [MySQL]


Sujet :

PHP & Base de données

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé
    Homme Profil pro
    Aprenti
    Inscrit en
    Mai 2015
    Messages
    199
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Canada

    Informations professionnelles :
    Activité : Aprenti

    Informations forums :
    Inscription : Mai 2015
    Messages : 199
    Par défaut Requêtes préparées (PDO) avec données trop volumineuses
    Bonjour,

    J'ai récupéré les données dans un array ($dataDistant) d'une basse de donnée externe.

    Ensuite, je vais mettre ces données dans une table d'une BDD interne.
    Mais cet "array" ($dataDistant) est trop lourd qui contient 96899 entrées.

    voici une partie de mon array obtenu :
    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
    print_r($dataDistant )
    /*
    Array
    (
        [0] => Array
            (
                [id] => 10000000
                [quantity] => 10
            )
     
        [1] => Array
            (
                [id] => 10000100
                [quantity] => 110
            )
     
        [2] => Array
            (
                [id] => 10000200
                [quantity] => 10
            )
    //....
    */
    Mais imaginez qu'il contient 96 899 entrées.
    Comment peux - je diviser en plusieurs morceaux ?


    En fait, avec cela je fais une requête préparée : voici un exemple de cette requête :
    Array ( [requestSQL] => INSERT INTO db_local_product (id,quantity ) VALUES (:id,:quantity ); [insertValues] => Array ( [:id] => 10000000 [:quantity] => 10 ) )
    Array ( [requestSQL] => INSERT INTO db_local_product (id,quantity ) VALUES (:id,:quantity ); [insertValues] => Array ( [:id] => 10000100 [:quantity] => 110 ) )
    Array ( [requestSQL] => INSERT INTO db_local_product (id,quantity ) VALUES (:id,:quantity ); [insertValues] => Array ( [:id] => 10000200 [:quantity] => 10 ) )
    etc...
    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
    private function req(array $result)
    {
    	$funcRequestSQL = "INSERT INTO table_int_product (id,quantity )
    			       VALUES (:id,:quantity );";
     
    	$insertValues = [
    		':id'=> $result['id'],
    		':quantity'=> $result['quantity'],								
    	];
    	return $requestMySql = [
    		'requestSQL' => $requestSQL,
    		'insertValues' => $insertValues,
    	];
    }
     
     
    //... $requetesDistant ... SELECT ....
     
    print_r($dataDistant);
    foreach($dataDistant as $result){
    	foreach($result as $key=>$value){
    		$requestMySql = $this-> funcRequestSQL($result);
     
    	}
    //... $conn ...
     try
            {
                $request = $conn->prepare($requestMySql['requestSQL']);
     
                $request->execute($requestMySql['insertValues']);
                $conn = null;
                return $status = "SUCCESSFULLY INSERTED ";
     
            }
            catch(\PDOException $e){
                self::errorSql ($e, $root, $storeSiteName, $systemName, $subject, $dbname); 
                $conn = null;
                throw $e;
            }
    Comment je peux executer mon script pour qu'il n'y a pas de erreur d’espace dans la mémoire tampon et que la file d’attente soit saturée ?
    Je pense que je dois diviser mon array ($dataDistant) mais comment ?

  2. #2
    Membre éclairé
    Homme Profil pro
    Aprenti
    Inscrit en
    Mai 2015
    Messages
    199
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Canada

    Informations professionnelles :
    Activité : Aprenti

    Informations forums :
    Inscription : Mai 2015
    Messages : 199
    Par défaut
    Citation Envoyé par tonton.odilon Voir le message
    ...
    Je pense que je dois diviser mon array ($dataDistant) mais comment ?
    Bonjour,
    Je pense que je peux couper par la fonction de PHP : array_chunk
    par chaque 1000 entrée donc,
    c'est quelque chose comme cela :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    array_chunk($dataDistant, 1000)
    Mais comment ?

  3. #3
    Expert confirmé
    Avatar de rawsrc
    Homme Profil pro
    Dev indep
    Inscrit en
    Mars 2004
    Messages
    6 142
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Dev indep

    Informations forums :
    Inscription : Mars 2004
    Messages : 6 142
    Billets dans le blog
    12
    Par défaut
    Salut,

    comme tu n'as que des valeurs numériques, j'opterais pour la simplicité :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    $parts = array_chunk($dataDistant, 10000, false);
     
    foreach ($parts as $values) {
        $values = array_map(function($p) { return "({$p['id']},{$p['quantity']})"; }, $values);
        $sql    =  'INSERT INTO table_int_product (id, quantity) VALUES '.implode(',', $values);
        runSql($sql); // fonction qui exécute le code sql à ta convenance
    }

  4. #4
    Membre éclairé
    Homme Profil pro
    Aprenti
    Inscrit en
    Mai 2015
    Messages
    199
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Canada

    Informations professionnelles :
    Activité : Aprenti

    Informations forums :
    Inscription : Mai 2015
    Messages : 199
    Par défaut
    Bonjour Rawsrc,
    Ça marche et un grand merci.
    C'est très intéressant : 'array_map' avec 'function'
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    array_map(function($p) { return "( {$p...)
    Il faut que je comprenne un peu mieux donc il faut que je l'apprenne mieux (dans ma logique...) pour l'utiliser.


    Une petite question puisque tu dis :
    Citation Envoyé par rawsrc Voir le message
    comme tu n'as que des valeurs numériques, j'opterais pour la simplicité :
    Dans l'avenir s'il y a de valeurs non numériques ? Que l'on doit faire ?

    Merci et bonne journée

  5. #5
    Modératrice
    Avatar de Celira
    Femme Profil pro
    Développeuse PHP/Java
    Inscrit en
    Avril 2007
    Messages
    8 633
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeuse PHP/Java
    Secteur : Industrie

    Informations forums :
    Inscription : Avril 2007
    Messages : 8 633
    Par défaut
    On est un peu en train de passer à côté de l'intérêt des requêtes préparées, qui est justement d'exécuter plusieurs fois la même requête avec des données différentes. (*)
    De plus, j'ai l'impression que tu fais la connexion à la base à l'intérieur de la boucle, ce qui est totalement inutile : une seule connexion peut faire toutes les insertions. Quand tu veux ranger 5 chemises dans ton placard, tu ne fermes pas le placard entre chaque chemise.

    Donc :
    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
    try {
        // on connecte à la base 
        $conn = include 'db_mysql.php'; // par exemple
     
     
        // on prépare une seule fois la requête : 
        $request = $conn->prepare("INSERT INTO table_int_product (id,quantity ) VALUES (:id,:quantity )");
     
        // on boucle sur les données à insérer
        foreach($dataDistant as $result){
             $request->execute([
                ':id'=> $result['id'],
                ':quantity'=> $result['quantity'],								
            ]);
        }    
    }catch(\PDOException $e){
        self::errorSql ($e, $root, $storeSiteName, $systemName, $subject, $dbname); 
        $conn = null;
        throw $e;
    }


    (*)Non, les requêtes préparées ne sont pas faites pour échapper les valeurs, c'est juste un effet de bord intéressant et utile.
    Modératrice PHP
    Aucun navigateur ne propose d'extension boule-de-cristal : postez votre code et vos messages d'erreurs. (Rappel : "ça ne marche pas" n'est pas un message d'erreur)
    Cherchez un peu avant poser votre question : Cours et Tutoriels PHP - FAQ PHP - PDO une soupe et au lit !.

    Affichez votre code en couleurs : [CODE=php][/CODE] (bouton # de l'éditeur) et [C=php][/C]

  6. #6
    Membre éclairé
    Homme Profil pro
    Aprenti
    Inscrit en
    Mai 2015
    Messages
    199
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Canada

    Informations professionnelles :
    Activité : Aprenti

    Informations forums :
    Inscription : Mai 2015
    Messages : 199
    Par défaut
    Bonjour Celira,
    Excellente idée et un grand merci.
    Ton idée va m'aider dans un cas similaire, mais un peut différent avec un "SELECT" et "fetch(PDO::FETCH_ASSOC)".


    Citation Envoyé par Celira Voir le message
    On est un peu en train de passer à côté de l'intérêt des requêtes préparées, qui est justement d'exécuter plusieurs fois la même requête avec des données différentes. (*)
    De plus, j'ai l'impression que tu fais la connexion à la base à l'intérieur de la boucle, ce qui est totalement inutile : une seule connexion peut faire toutes les insertions.
    Quand tu veux ranger 5 chemises dans ton placard, tu ne fermes pas le placard entre chaque chemise.
    Tu es raison , quand je ne pense pas trop, on est fatigué en répétant la même geste inutile...

    Bonne journée

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

Discussions similaires

  1. [2.x] Envoi d'une requête SOAP/wsdl avec données XML
    Par Mouke dans le forum Symfony
    Réponses: 0
    Dernier message: 05/02/2016, 13h00
  2. [MySQL] requête préparée PDO avec varibale
    Par rvm31 dans le forum PHP & Base de données
    Réponses: 1
    Dernier message: 11/01/2016, 21h02
  3. [TinyMCE] Requête préparée pdo
    Par Invité dans le forum Bibliothèques & Frameworks
    Réponses: 4
    Dernier message: 12/03/2014, 20h29
  4. [PDO] Requête préparée PDO
    Par ben256xp dans le forum PHP & Base de données
    Réponses: 9
    Dernier message: 03/06/2013, 09h47
  5. Requête 2 Tables avec donnée supplémentaire
    Par hervesz dans le forum Débuter
    Réponses: 2
    Dernier message: 28/10/2012, 15h52

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