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 :

Insertion en double


Sujet :

PHP & Base de données

  1. #1
    Membre régulier
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2003
    Messages
    176
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Nouvelle-Calédonie

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Mai 2003
    Messages : 176
    Points : 75
    Points
    75
    Par défaut Insertion en double
    Bonjour à tous

    Voilà la fonction que j'utilise :
    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
    function peuplerTable(){
    	$req = $connexion->prepare("INSERT INTO $tbl (cli_code,cli_civilite) VALUES(?,?)");
    	$values =array("100000","");
    	$nbCli=100;
    	for($i=0; $i<=$nbCli; $i++){
    		$noCli=$values[0];
    		$noCli++;
    		$values[0]=(string)$noCli;
    		try {
    			$result =$req->execute($values);
    		}catch(PDOException $e){
    			return $e->getCode()."\n".$e->getMessage();
    		}
    	}
    	return true;
    }
    à l’exécution j'ai l'erreur suivante :
    message = "faultCode:INVALID_AMF_MESSAGE faultString:'Invalid AMF message' faultDetail:'
    Fatal error: Maximum execution time of 30 seconds exceeded in C:\wamp\www\amfphp\services\gesbox.php on line 127
    Environ 60 requêtes sont exécutées (les lignes existent bien dans la table) et l'erreur ci-dessus arrive.
    Il semblerait que le "Maximum execution time" soit appliqué sur l'ensemble des requêtes de la boucle !! Comment est-ce possible ,
    Si c'est le cas, comment faire pour que le "Maximum execution time" soit applicable a chaque requête de la boucle.

    Merci de vos réponses
    YC

  2. #2
    Membre à l'essai
    Homme Profil pro
    Développeur Web
    Inscrit en
    Mars 2012
    Messages
    16
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Mars 2012
    Messages : 16
    Points : 21
    Points
    21
    Par défaut
    Bonjour,

    Ce lien peut peut-être t'aider:
    http://ziprof.free.fr/PHP-MYSQL/Maxi...amp-erreur.php

  3. #3
    Membre régulier
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2003
    Messages
    176
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Nouvelle-Calédonie

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Mai 2003
    Messages : 176
    Points : 75
    Points
    75
    Par défaut
    Merci pour ta réponse.

    Effectivement si j'augmente " Maximum execution time" dans mon php.ini (je l'ai porté à 3600, 1heure) ça fonctionne.

    Mais là, j'ai une vrai interrogation !
    A quoi correspond exactement le "Maximum execution time" de php.
    Je pensais que ça correspondait à l’exécution D'UNE seule requête. Comment se fait-il que dans mon cas ça porte sur l'ensemble des requêtes de la boucle ?
    Dans ce cas ça devrait porter aussi sur l'ensemble des requêtes de l'application ??
    Je ne comprend plus rien !!

    YC

  4. #4
    Membre régulier
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2003
    Messages
    176
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Nouvelle-Calédonie

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Mai 2003
    Messages : 176
    Points : 75
    Points
    75
    Par défaut
    Ou alors le "Maximum execution time" porte sur l'ensemble des requêtes d'une session (ouverture/fermeture) de la base MySQL

    S'il vous plait, si quelqu'un sait, ce que je pense, expliquez-moi comment fonctionne ce foutu "Maximum execution time".

    Merci de vos réponses.
    YC

  5. #5
    Membre à l'essai
    Homme Profil pro
    Développeur Web
    Inscrit en
    Mars 2012
    Messages
    16
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Mars 2012
    Messages : 16
    Points : 21
    Points
    21
    Par défaut
    Voici ce qu'il faut savoir à ce propos:
    http://php.net/manual/fr/function.set-time-limit.php

    Cela te permet donc de fixer des délais max d'exécution pour éviter que si ton script par dans une boucle infinie, il ne sature (pas trop, ou de trop...) le serveur.

    Tu peux carrément enlever cette limite en mettant la valeur 0 (largement déconseillé).

    Ce n'est donc pas par rapport à ta requête SQL directement mais par rapport au script PHP, le temps d'exécution de ce dernier.

    Toutefois si ton script mets plus de 30 secondes à s'exécuter, je crois qu'il y a un petit soucis non ?

    Luis

  6. #6
    Membre averti

    Homme Profil pro
    Développeur Web
    Inscrit en
    Juin 2011
    Messages
    205
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Juin 2011
    Messages : 205
    Points : 409
    Points
    409
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par luisf Voir le message
    Toutefois si ton script mets plus de 30 secondes à s'exécuter, je crois qu'il y a un petit soucis non ?
    Je suis assez d'accord, et modifier la valeur de cette directive de configuration est une mauvaise idée.

    Tu devrais chercher d'autres moyens d'optimiser ton code, en renvoyant ta requête, faire des insertions par lots par exemple !
    si ce post vous a été utile, si votre problème est résolu.
    Pensez-y !
    __________________________________
    Doc officielle PHP | FAQ PHP | Cours PHP

  7. #7
    Membre actif
    Profil pro
    Inscrit en
    Décembre 2008
    Messages
    127
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2008
    Messages : 127
    Points : 208
    Points
    208
    Par défaut
    Bonjour,

    100% d'accord avec k"amm, s'il fallait modifier les paramètres d'un serveur à chaque time out, on s'en sortirait avec des time out infinis !

    J'ai essayé ta fonction sur mon serveur local et j'ai un dépassement de temps à partir de 500 lignes créées (il est à 30 secondes aussi chez moi).
    Par contre, j'ai réécrit ta fonction en faisant un insert direct sans sqlprepare et pour 800 record, c'est instantané, ni plus ni moins !
    je l'ai fait avec mysqli et pas pbo, mais dans mon test précédant, j'avais aussi fait avec musqli, donc ce n'est pas le problème.

    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
    /* fonction beaucoup plus rapide */
    function peuplerTableBis($connexion,$tbl){
            $reqsql = "INSERT INTO $tbl (cli_code,cli_civilite) VALUES ";
    		$values =array("100000","");
    		$nbCli=800;
    		for($i=0; $i<=$nbCli; $i++){
    			$noCli=$values[0];
    			$noCli++;
    			$values[0]=(string)$noCli;
    			$reqsql .= "('" . $values[0] . "','" . $values[1] . "')";
    			if ($i < $nbCli) {
    			  $reqsql .= ",";
    			}
    		}
    		if (isset($debug)) {
    		  echo "<br>Lancement requete <br>" .$reqsql;
    		}
    			try {
    				$result =$connexion->query($reqsql);
    			}catch(PDOException $e){
    				return $e->getCode()."\n".$e->getMessage();
    		}
    		return "ok";
    	}
    Cordialement

  8. #8
    Membre régulier
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2003
    Messages
    176
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Nouvelle-Calédonie

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Mai 2003
    Messages : 176
    Points : 75
    Points
    75
    Par défaut
    C'est sûr que c'est beaucoup plus rapide !!
    Mais si on ne fait plus de "prepare" ne risque-t-il pas y avoir de problème de sécurité ?

  9. #9
    Membre éprouvé
    Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mars 2009
    Messages
    552
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Mars 2009
    Messages : 552
    Points : 1 060
    Points
    1 060
    Par défaut
    Si, mais il y a
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $connection->quote( $str )
    pour corriger ça.
    http://php.net/manual/fr/pdo.quote.php

  10. #10
    Expert éminent sénior
    Avatar de rawsrc
    Homme Profil pro
    Dev indep
    Inscrit en
    Mars 2004
    Messages
    6 142
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    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
    Points : 16 545
    Points
    16 545
    Billets dans le blog
    12
    Par défaut
    Salut,

    Et avec ceci tu montes à combien
    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
    function peuplerTable(PDO $connexion, $tbl)
    {
        $values = array('100000', '');
        $nbCli  = 800;
        try
        {
            /** @var \PDOStatement */
            $req    = $connexion->prepare("INSERT INTO {$tbl} (cli_code, cli_civilite) VALUES (:code, :civ)");
            $req->bindValue(':civ', $values[1]);
     
            for ($i = 0; $i < $nbCli; ++$i)
            {
                $req->bindParam(':code', $v = $values[0]++);
                $req->execute();
            }
        }
        catch (\PDOException $e)
        {
            return $e->getCode()."\n".$e->getMessage();
        }
     
        return true;
    }

  11. #11
    Membre actif
    Profil pro
    Inscrit en
    Décembre 2008
    Messages
    127
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2008
    Messages : 127
    Points : 208
    Points
    208
    Par défaut
    Bonjour, et Eureka !

    La clé est d'empêcher l'autocomit qui doit ouvrir une transaction à chaque execute ;

    En reprenant le code initial, il suffit de mettre un begintransacton avant la boucle et un comit après la boucle et l'insertion de 800 records se fait quasi instatanné.
    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
    function peuplerTable($connexion,$tbl){
    		$req = $connexion->prepare("INSERT INTO $tbl (cli_code,cli_civilite) VALUES(?,?)");
    		$values =array("100000","");
    		$nbCli=801;
    		$req->bindparam(1, $values[0]);
    		$req->bindparam(2, $values[1]);
    		$connexion->beginTransaction();
    		for($i=0; $i<=$nbCli; $i++){
    			$noCli=$values[0];
    			$noCli++;
    			$values[0]=(string)$noCli;
    			try {
    				$result =$req->execute();
    			}catch(PDOException $e){
    				return $e->getCode()."\n".$e->getMessage();
    			}
    		}
    		$connexion->commit();
    		return $req->rowcount();
    	}
    Cordialement

Discussions similaires

  1. Requête d'insertion avec double sélection
    Par Viammi dans le forum Langage SQL
    Réponses: 12
    Dernier message: 05/05/2012, 22h55
  2. Problème d'insertion avec double TIMESTAMP
    Par Tchupacabra dans le forum SQL Procédural
    Réponses: 4
    Dernier message: 03/12/2007, 09h23
  3. Insertion en double dans ma bdd
    Par n@n¤u dans le forum Hibernate
    Réponses: 13
    Dernier message: 20/07/2007, 15h33
  4. [Oracle] Insertions en double
    Par tonton93 dans le forum PHP & Base de données
    Réponses: 1
    Dernier message: 28/03/2007, 20h39
  5. [MySQL] Insertion en double
    Par warmup27 dans le forum PHP & Base de données
    Réponses: 8
    Dernier message: 02/11/2006, 18h18

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