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 :

Problème doublement des insert.


Sujet :

PHP & Base de données

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Juillet 2009
    Messages
    10
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2009
    Messages : 10
    Par défaut Problème doublement des insert.
    Bonjour à tous,

    je programme actuellement une appli pour gérer une facturation téléphonique mais je rencontre un étrange problème lorsque je traite le fichier csv où je récupère les différentes données.
    En effet lorsque je traite mon fichier de 35k lignes je me retrouve avec 70k lignes dans ma table...
    j'ai fais un echo des requetes il en fait 35k je comprend pas pourquoi je me retrouve avec ces 70k lignes.

    Voici la zone qui en ce moment pose 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
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    	include "connexion_aftel.inc";
     
    	// RECUPERATION DU NUMERO DE LA FACTURE IMPORTEE
    	$requete  = " select distinct c from imports ";
    	$resultat = @mysql_query($requete);
    	while ($tableau = @mysql_fetch_array($resultat)){ 
    		$numero_facture_import = addslashes($tableau["c"]);	
    	}
    	$requete  = " select numero_facture from factures where numero_facture='".$numero_facture_import."'";
    	$resultat = @mysql_query($requete);
    	$nb_resultat = mysql_num_rows($resultat);
    	echo $nb_resultat;
     
     
    	if($nb_resultat==0){
    		// TRT DU FICHIER IMPORTS SI LE TRAITEMENT N'A PAS DEJA ETE FAIT
    		$requete  = " select * from imports ";
    		$resultat = @mysql_query($requete);
    		while ($tableau = @mysql_fetch_array($resultat)){ 
    			$compte_facturation = $tableau["a"];
    			$numero_facture = addslashes($tableau["c"]);	
    			$date_facture = addslashes($tableau["d"]);
    			$poste_appelant = addslashes($tableau["j"]);
    			$date_appel = date("Y-m-d",strtotime(substr($tableau["l"],3,2)."/".substr($tableau["l"],0,2)."/".substr($tableau["l"],6,4)));
    			$heure_appel = addslashes($tableau["m"]);
    			$unites_facturees = addslashes($tableau["n"]);
    			$unites_appel = addslashes($tableau["o"]);	
    			$post_appele = addslashes($tableau["q"]);
    			$destination = addslashes($tableau["r"]);
    			$id_juridiction = addslashes(substr($tableau["t"],0,1));
    			$montant_appel = str_replace(",",".",addslashes($tableau["u"]));
     
    			$requete  = "insert into appels values(";
    			$requete .= "null,";
    			$requete .= "'".$poste_appelant."',";
    			$requete .= "'".$id_juridiction."',";
    			$requete .= "'".$numero_facture."',";
    			$requete .= "'".$date_appel."',"; 
    			$requete .= "'".$heure_appel."',";
    			$requete .= "'".$unites_facturees."',";
    			$requete .= "'".$unites_appel."',";
    			$requete .= "'".$montant_appel."',";
    			$requete .= "'".$post_appele."',";
    			$requete .= "'".$destination."',";
    			$requete .= "'0')";
     
    			$insert = mysql_query($requete)  or die(mysql_error());
    		}
     
     
    		// EN FIN DE TRT INSERTION DU NUMERO DE LA FACTURE DANS LA TABLE FACTURES. 
    		$requete  = "insert into factures values('".$numero_facture."','".date("Y-m-d",strtotime($date_facture))."','".$compte_facturation."')";
    		$insert = @mysql_query($requete);	
     
    	}
    Si quelqu'un à une petite idée cela m'aiderai vraiment.

    Adrien.

  2. #2
    Membre Expert Avatar de RunCodePhp
    Profil pro
    Inscrit en
    Janvier 2010
    Messages
    2 962
    Détails du profil
    Informations personnelles :
    Localisation : Réunion

    Informations forums :
    Inscription : Janvier 2010
    Messages : 2 962
    Par défaut
    Salut

    j'ai fais un echo des requetes il en fait 35k je comprend pas pourquoi je me retrouve avec ces 70k lignes.
    Ou est ce que tu as fais le echo, à quel moment dans le code, quelle ligne ?
    De plus, je ne vois pas de code qui concerne le parcourt d'un fichier CSV, mais que des requêtes.

    Si c'est une requête, fait un echo mysql_num_rows() juste avant la boucle pour savoir combien de lignes elle retourne.

    De plus, tu fais une première requête sur la table "facture" pour savoir si la facture existe.
    Ensuite, si elle n'existe pas, tu récupère tout, (sans un critère) de la table "import" pour créer toutes les lignes dans la table "facture".

    A mon avis, il faudrait sélectionner la même facture ($numero_facture_import) qui théoriquement n'existe pas, et uniquement celle ci, et la récupérer de la table "import", pour ensuite l'insérer dans la table "facture".
    Mais pas les autres, sinon il y aura doublon, voir triplon, quadruplon etc ...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    select * from imports where numero_facture = $numero_facture_import
    Un truc du genre.

    Ce qui m'étonne malgré tout, c'est que la requête qui insère les données dans la table "facture", elle est exécutée après la boucle de "import".
    Du coup, et théoriquement, s'il y a plusieurs lignes, ça sera la dernière qui sera prise en compte.
    Ceci dit, si tu corrige en sélectionnant qu'une seule facture, la boucle ne sera plus nécessaire, car une facture devrait être unique, donc n'avoir qu'une seule ligne de récupérée.

  3. #3
    Membre du Club
    Profil pro
    Inscrit en
    Juillet 2009
    Messages
    10
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2009
    Messages : 10
    Par défaut
    Salut,

    je fais l'echo derrière l'insert ce qui me flanque donc la totalité des insert créés.

    le code pour le csv est à part il ne sert qu'a traiter ce fichier et à l'importer dans la table imports.

    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
    40
    41
    42
    43
    44
    45
    <?php
    		if(isset($_FILES['import_csv']))
    		{ 
    			$dossier = 'csv/';
    			$fichier = basename($_FILES['import_csv']['name']);
    			$nom_temporaire = $_FILES['import_csv']['tmp_name'];
    			$extensions = '.csv';
    			$extension_fichier = strrchr($_FILES['import_csv']['name'], '.');// récupère la partie de la chaine à partir du dernier . pour connaître l'extension.
     
    			include "connexion_aftel.inc";
     
    			// création de la requête sql.
     
    			$requete  = " LOAD DATA INFILE '/Program Files/OCS Inventory NG/xampp/htdocs/web_services_dst/web_services/aftel/csv/".$fichier."'";
    			$requete .= " INTO TABLE imports ";
    			$requete .= " FIELDS TERMINATED BY ';' ENCLOSED BY '\"' ";
    			$requete .= " LINES TERMINATED BY '\\r\\n' " ;
    			$requete .= " IGNORE 1 LINES ";
    			//Vérification du format fichier, on doit récupérer un fichier csv.
    			if($extension_fichier != $extensions)
    			{
    				$erreur = 'Vous devez importer un fichier de type csv.';
    			}
    			if(!isset($erreur))
    			{
     
    				if(move_uploaded_file($nom_temporaire, $dossier.$fichier))
    				{
    					mysql_query("TRUNCATE TABLE `imports` "); 
    					mysql_query($requete);
     
    					echo 'import effectué avec succès !';
    				}
    				else
    				{
    					echo 'Echec de l\'import !';
    				}
    			}
    			else
    			{
    				echo $erreur;
    			}
     
    		}	
    ?>
    Donc à chaque import ma table est vidée, je ne peu pas avoir de doublon normalement

    j'exécute ma requête dans la boucle normalement il devrait y avoir autant d'insert que de passage dans la boucle...et non pas le double

  4. #4
    Membre Expert Avatar de RunCodePhp
    Profil pro
    Inscrit en
    Janvier 2010
    Messages
    2 962
    Détails du profil
    Informations personnelles :
    Localisation : Réunion

    Informations forums :
    Inscription : Janvier 2010
    Messages : 2 962
    Par défaut
    Tu ne dis pas tout de même que c'est la table "imports" qui insert les données en double, on le déduit.

    Si c'est bien ça, c'est vrai que le fait de vider la table en 1er ne devrait pas provoquer de doublon.
    Du coup, c'est à se demander si ce ne serait pas le fichier CSV qui n'irait pas.

    Tu parle de 35k lignes, donc de 35 milles lignes, si c'est ça, je doute un peu que tu t'es amusé à compter manuellement le nombre de lignes.
    Si c'est le cas, alors c'est un code qui t'as retourné cette info.
    Du coup, question : Comment as tu obtenu le nombre de ligne ? Cette info est elle fiable ?

    Comme ça, au feeling, as tu tenter de toi même vider cette table (via PhpMyAdmin par exemple), et de le vérifier IN VISU ?
    As tu tenté aussi de vider, et de l'importer manuellement ?
    On pourrait tirer des conclusions en faisant de tels essaient.


    Mise à part ça, je ne vois pas d'autres pistes.


    j'exécute ma requête dans la boucle normalement il devrait y avoir autant d'insert que de passage dans la boucle...et non pas le double
    Tu précise jamais de quelle table, et quelle boucle

    Mais n'empêche que le déroulement des opérations sont quelque peu déroutantes, du faite justement que cette requête d'insertion de la table "facture" se fasse après la boucle, et non pas dans la boucle.
    Seule l'insertion de la table "appels" est dans la boucle.
    Ca ne peut être QUE la dernière ligne qui sera enregistrée.
    Comment être certain que c'est celle ci qui doit l'être ? Et pourquoi pas la précédente par exemple ?
    Et pourquoi pas toutes les lignes au lieu d'une seule ?
    (bizarre comme principe tout de même).

  5. #5
    Membre du Club
    Profil pro
    Inscrit en
    Juillet 2009
    Messages
    10
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2009
    Messages : 10
    Par défaut
    En effet je ne me suis pas amuser à compter les 35000 requetes affichées.
    -j'ai tout sélectionné et mis dans notepad++.
    -j'avais aussi mis une variable qui s'incrémentait à chaque passage de la boucle du traitement fichier import:

    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
    	if($nb_resultat==0){
    		// TRT DU FICHIER IMPORTS SI LE TRAITEMENT N'A PAS DEJA ETE FAIT
    		$requete  = " select * from imports ";
    		$resultat = @mysql_query($requete);
    		$i=0;
    		while ($tableau = @mysql_fetch_array($resultat)){ 
    			$i++;
    			$compte_facturation = $tableau["a"];
    			$numero_facture = addslashes($tableau["c"]);	
    			$date_facture = addslashes($tableau["d"]);
    			$poste_appelant = addslashes($tableau["j"]);
    			$date_appel = date("Y-m-d",strtotime(substr($tableau["l"],3,2)."/".substr($tableau["l"],0,2)."/".substr($tableau["l"],6,4)));
    			$heure_appel = addslashes($tableau["m"]);
    			$unites_facturees = addslashes($tableau["n"]);
    			$unites_appel = addslashes($tableau["o"]);	
    			$post_appele = addslashes($tableau["q"]);
    			$destination = addslashes($tableau["r"]);
    			$id_juridiction = addslashes(substr($tableau["t"],0,1));
    			$montant_appel = str_replace(",",".",addslashes($tableau["u"]));
     
    			$requete_appels = "insert into appels values(";
    			$requete_appels .= "null,";
    			$requete_appels .= "'".$poste_appelant."',";
    			$requete_appels .= "'".$id_juridiction."',";
    			$requete_appels .= "'".$numero_facture."',";
    			$requete_appels .= "'".$date_appel."',"; 
    			$requete_appels .= "'".$heure_appel."',";
    			$requete_appels .= "'".$unites_facturees."',";
    			$requete_appels .= "'".$unites_appel."',";
    			$requete_appels .= "'".$montant_appel."',";
    			$requete_appels .= "'".$post_appele."',";
    			$requete_appels .= "'".$destination."',";
    			$requete_appels .= "'0');";
     
    			$insert = @mysql_query($requete_appels) or die(mysql_error());			
    		}
    		echo $i;

    Je pense que c'est fiable comme info mais j'obtiens toujours 35k ligne en visu mais 70k dans la tables appels.

    J'ai vidé mes tables, j'ai sélectionné à la main les 35k lignes affichées, que j'ai envoyé directement via PHPmyadmin et là j'ai mon bon nombre d'insert.

    Citation:
    j'exécute ma requête dans la boucle normalement il devrait y avoir autant d'insert que de passage dans la boucle...et non pas le double
    Tu précise jamais de quelle table, et quelle boucle
    désolé de ne pas être très clair je suis débutant et j'ai un peu de mal a m'expliquer

    donc la requête d'insertion pour la table appels est effectuées à chaque passage dans la boucle du traitement du fichier import. donc ça m'effectue 35k requêtes.

    J'ai essayer de mettre l'exécution de la requête après ma boucle imports en concaténant tous mes insert dans une seul variable mais j'ai un message d'erreur...
    You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ';insert into appels values(null,'247251088','L','9A0002606917','2009-12-01','09:' at line 1
    autre bizarrerie j'affiche le contenue de cette variable je sélectionne tout, j'envois via phpmyadmin et là pas d'erreur.


    En tout cas merci d'essayer de m'aider car je suis dépassé devant ces abérrations.

  6. #6
    Membre Expert Avatar de RunCodePhp
    Profil pro
    Inscrit en
    Janvier 2010
    Messages
    2 962
    Détails du profil
    Informations personnelles :
    Localisation : Réunion

    Informations forums :
    Inscription : Janvier 2010
    Messages : 2 962
    Par défaut
    Je pense que c'est fiable comme info mais j'obtiens toujours 35k ligne en visu mais 70k dans la tables appels.
    Ce n'était donc pas la table "imports" qui avait le doublon, mais "appels";
    Faut suivre

    Ce qui serait pas mal, c'est de supprimer tous ces @ devant les fonctions.
    Ca sert à rien, même pire, on obtiendra rien en cas d'erreur.
    (Il vaut mieux utiliser la directive "display_errors" du php.ini, On ou Off si on souhaite ou pas afficher les erreurs. Comme tu est en train de débugger, vaut mieux les faire afficher).


    Etant donné que le $i affiche bien 35k lignes, tu pourrais mettre un point d'arrêt juste après le echo $i :
    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
     
    		while ($tableau = @mysql_fetch_array($resultat)){ 
    			$i++;
    			... etc ...
    			$requete_appels = "insert into appels values(";
    			... etc ...
    			$requete_appels .= "'0')";
     
    			$insert = mysql_query($requete_appels) or die(mysql_error());			
    		}
    		echo $i;
    		//
    		$rs = mysql_query('SELECT COUNT(*) AS total FROM appels');
    		$totalAppels = mysql_fetch_array($rs);
    		echo 'Total : '.$totalAppels['total'];
    		exit(); // On stop tout ici
    Ensuite vérifier s'il y a encore doublon ou pas dans la Bdd grace à la requête supplémentaire (provisoirement).


    Ceci dit, je reste d'avis que normalement, la sélection sur la table "imports" devrait être se limiter à 1 seule facture, et non toutes.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    $requete  = " select numero_facture from factures where numero_facture='".$numero_facture_import."'";
     
    if($nb_resultat==0){
    C'est ceci qui le conditionne.
    La suite devrait alors tenir compte de la facture ci-dessus.
    -> SELECT * from imports WHERE n°facture = 1 seule facture
    C'est sous cette condition que tout ces traitements sont lancés ou pas.
    Donc pas pour n'importe quelle facture.
    Tout ceci n'a peut être aucun rapport avec le problème, mais il y a des trucs pas logiques quand même.


    for the right syntax to use near ';
    Le message dit qu'il y a un problème de syntaxe au niveau du ; (point virgule).
    Supprime le (ici) : $requete_appels .= "'0'); <- En trop

    donc la requête d'insertion pour la table appels est effectuées à chaque passage dans la boucle du traitement du fichier import. donc ça m'effectue 35k requêtes.
    Oui, pour la table "appels" mais pas pour la table "facture" :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    		$requete  = " select * from imports ";
    		$resultat = @mysql_query($requete);
    		while ($tableau = @mysql_fetch_array($resultat)){ 
    			... etc ...
    			$insert = mysql_query($requete)  or die(mysql_error());
    		}
     
    		// EN FIN DE TRT INSERTION DU NUMERO DE LA FACTURE DANS LA TABLE FACTURES. 
    		$requete  = "insert into factures values('".$numero_facture."','".date("Y-m-d",strtotime($date_facture))."','".$compte_facturation."')";
    		$insert = @mysql_query($requete);
    Ici, l'insertion dans la table "facture" se fait après la boucle.
    Cependant, elle exploite des données qui viennent de cette boucle (comme $numero_facture).
    S'il y a boucle, plusieurs lignes, l'insertion ne se fera qu'une seule fois (1 ligne) et QUE pour la dernière ligne.
    Mais encore une fois, ceci n'a peut être aucun rapport avec le problème de doublon, mais il y a des trucs pas clairs malgré tout.

  7. #7
    Membre du Club
    Profil pro
    Inscrit en
    Juillet 2009
    Messages
    10
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2009
    Messages : 10
    Par défaut
    Bon j'ai effectué le teste que tu m'as écris et là je suis encore plus perdu .

    Étant donné que le $i affiche bien 35k lignes, tu pourrais mettre un point d'arrêt juste après le echo $i :
    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
    Code :
     
     
    		while ($tableau = @mysql_fetch_array($resultat)){ 
    			$i++;
    			... etc ...
    			$requete_appels = "insert into appels values(";
    			... etc ...
    			$requete_appels .= "'0')";
     
    			$insert = mysql_query($requete_appels) or die(mysql_error());			
    		}
    		echo $i;
    		//
    		$rs = mysql_query('SELECT COUNT(*) AS total FROM appels');
    		$totalAppels = mysql_fetch_array($rs);
    		echo 'Total : '.$totalAppels['total'];
    		exit(); // On stop tout ici

    Ensuite vérifier s'il y a encore doublon ou pas dans la Bdd grace à la requête supplémentaire (provisoirement).
    le résultat : $i=35448 Total : 46007

    devant ce résultat étonnant j'ai regardé ma table "appels" dans phpmyadmin et il y'a 70896 entrées .

    Ceci dit, je reste d'avis que normalement, la sélection sur la table "imports" devrait être se limiter à 1 seule facture, et non toutes.
    La sélection du numéro de facture n'est la que pour vérifier si cette facture n'a pas déjà été traitée.
    le fichier csv traité ne contient qu'une seul facture donc dans ma table imports je n'ai jamais de numéro de facture différent.

    c'est pour ça que j'effectue l'insert de mon numéro de facture dans la table factures, comme toutes les lignes on le même numéro.

  8. #8
    Membre Expert Avatar de RunCodePhp
    Profil pro
    Inscrit en
    Janvier 2010
    Messages
    2 962
    Détails du profil
    Informations personnelles :
    Localisation : Réunion

    Informations forums :
    Inscription : Janvier 2010
    Messages : 2 962
    Par défaut
    le résultat : $i=35448 Total : 46007

    devant ce résultat étonnant j'ai regardé ma table "appels" dans phpmyadmin et il y'a 70896 entrées .
    Ca ne s'arrange pas, effectivement.

    Il y a des trucs qui partent en quenouille, c'est clair
    C'est peut être lié aux codes présents dans la boucle, des truc pas zen peut être.
    C'est peut être lié à un manque de mémoire. 35000 lignes en boucle + insertion en boucle toujours, c'est quand même beaucoup.
    Ou encore à un timeout.

    As tu rectifié/supprimé les @ ?
    Et faire afficher les retours d'erreurs éventuels ? (display_errors -> On)
    C'est important, même hyper important, car si tu n'est pas au courant d'une erreur (ou plusieurs) dans cette étape particulièrement, c'est vraiment tourner en rond.
    Il vaut mieux être informé de suite, se qui permettra de débugger.

    Il aurait fallut aussi avoir le total que retourne la table "imports"
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    $requete  = " select * from imports ";
    $resultat = mysql_query($requete);
    echo 'Total imports : '.mysql_num_rows($resultat).'<br />';
    $i=0;
    ... etc ...
    Je ne vois pas d'autres manière que de supprimer en 1er tous les traitements qui se trouvent dans cette boucle.
    Ne conserver que les 2 echo et le $i.
    Et espérer que ces 2 infos retournent le même nombre, ce qui doit être le cas.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    		echo 'Total imports : '.mysql_num_rows($resultat).'<br />';
    		while ($tableau = mysql_fetch_array($resultat)){ 
    			$i++;		
    		}
    		echo $i;
    		//
    		exit(); // On stop tout ici
    Faudrait le faire plusieurs fois pour voir si c'est à chaque fois le même nombre, que ça soit stable, pour les 2 echos.
    Si par chance c'est le même nombre (et celui attendu), alors peut être réintégrer le code en douceurs, petit morceau par petit morceau.
    Peut être d'ailleurs créer une nouvelle table (provisoire, genre appels_essai) et y mettre 1 seul champ en auto_increment, et y faire une insertion.
    Vérifier que le nombre inséré soit celui attendu.
    ... etc ... etc ...
    Etape par étape.

  9. #9
    Membre du Club
    Profil pro
    Inscrit en
    Juillet 2009
    Messages
    10
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2009
    Messages : 10
    Par défaut
    Bonjour, aller c'est repartit pour essayer de comprendre

    Bon j'ai viré tous les '@', j'ai activer 'diplay_errors -> on' mais pas de message d'erreur

    Il aurait fallut aussi avoir le total que retourne la table "imports"
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    Code :
     
    $requete  = " select * from imports ";
    $resultat = mysql_query($requete);
    echo 'Total imports : '.mysql_num_rows($resultat).'<br />';
    $i=0;
    ... etc ...

    Je ne vois pas d'autres manière que de supprimer en 1er tous les traitements qui se trouvent dans cette boucle.
    Ne conserver que les 2 echo et le $i.
    Et espérer que ces 2 infos retournent le même nombre, ce qui doit être le cas.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    Code :
     
     
    		echo 'Total imports : '.mysql_num_rows($resultat).'<br />';
    		while ($tableau = mysql_fetch_array($resultat)){ 
    			$i++;		
    		}
    		echo $i;
    		//
    		exit(); // On stop tout ici
    résultat la table imports retourne 30k de même en sortie de boucle. je l'ai fais plusieurs fois toujours pareil.

    J'ai donc créé une table 'test' avec un seul champ auto_increment et là le nombre d'insert dans la table test a de nouveau doublé.

    C'est peut être lié à un manque de mémoire. 35000 lignes en boucle + insertion en boucle toujours, c'est quand même beaucoup.
    j'ai essayer avec un plus petit fichier 1000 lignes le résultat reste le même.

  10. #10
    Membre Expert Avatar de RunCodePhp
    Profil pro
    Inscrit en
    Janvier 2010
    Messages
    2 962
    Détails du profil
    Informations personnelles :
    Localisation : Réunion

    Informations forums :
    Inscription : Janvier 2010
    Messages : 2 962
    Par défaut
    Bon j'ai viré tous les '@', j'ai activer 'diplay_errors -> on' mais pas de message d'erreur
    Bon, et bien si c'est pas lié à une erreur de code, ce serait une lié à une erreur de logique (ce qui est le moins évident à trouver).

    résultat la table imports retourne 30k de même en sortie de boucle. je l'ai fais plusieurs fois toujours pareil.

    J'ai donc créé une table 'test' avec un seul champ auto_increment et là le nombre d'insert dans la table test a de nouveau doublé.
    A ben là il y a une piste.
    Ca mérite d'être confirmer, d'être précis
    Tu veux dire que dans la Bdd il y aurait 30k lignes, et que le echo $i en sortie affiche bien 30k lignes ?
    Et que part contre, il y aurait le double dans la table "test" ?

    Si c'est bien ça, il aurait fallut remettre ton code pour l'insertion.
    En tout cas, toujours si c'est bien ça, ce serait dans la boucle que ça coince (et ça vaut mieux d'ailleurs).

    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
    <?php
    //
    include "connexion_aftel.inc";
    // $link est la ressource de la connexion
    //
    mysql_query('TRUNCATE TABLE test', $link);
    //
    $sql  = " select * from imports ";
    $rs_import = mysql_query($sql, $link);
    echo 'Total imports : '.mysql_num_rows($rs_import).'<br />';
    $cpt = 0;
    while ($table = mysql_fetch_array($rs_import)){ 
    	$cpt++;
    	mysql_query('INSERT INTO test (id) VALUES (NULL)', $link);
    }
    echo 'cpt  : '.$cpt;
    //
    exit(); // On stop tout ici
    ?>
    Je mets un code théoriquement complet (sans erreur j'espère).
    J'ai changé volontairement les noms des variables, sait on jamais.
    J'ai aussi rajouter des $link (ressource de connexion), il faudrait cependant rectifier le nom par rapport à celui dans "connexion_aftel.inc". Là aussi sait on jamais.

    Ca serait bien que ce truc fonctionne sans doublon.

  11. #11
    Membre du Club
    Profil pro
    Inscrit en
    Juillet 2009
    Messages
    10
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2009
    Messages : 10
    Par défaut
    bon le problème doit venir d'ailleurs, je m'explique

    j'ai pris le beau code que tu as fais j'ai créé un nouveau fichier je l'ai exécuté seul sans passer par l'interface que j'ai créée et là miracle tout va bien 30k lignes dans la table test!

    je rajoute donc le code pour insertion dans ma table 'appels' j'exécute toujours à part et là encore un jolie 30k lignes dans ma table.

    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
    40
    41
    42
    43
    44
    45
    46
    47
    <?php
    //
    include "connexion_aftel.inc";
    // $link est la ressource de la connexion
    //
    $cxn = mysql_connect("$host","$user","$pwd");
    //
    $sql  = " select * from imports ";
    $rs_import = mysql_query($sql, $cxn);
    echo 'Total imports : '.mysql_num_rows($rs_import).'<br />';
    $cpt = 0;
    while ($table = mysql_fetch_array($rs_import)){ 
    	$cpt++;
    			$compte_facturation = addslashes($tableau["a"]);
    			$numero_facture = addslashes($tableau["c"]);	
    			$date_facture = addslashes($tableau["d"]);
    			$poste_appelant = addslashes($tableau["j"]);
    			$date_appel = date("Y-m-d",strtotime(substr($tableau["l"],3,2)."/".substr($tableau["l"],0,2)."/".substr($tableau["l"],6,4)));
    			$heure_appel = addslashes($tableau["m"]);
    			$unites_facturees = addslashes($tableau["n"]);
    			$unites_appel = addslashes($tableau["o"]);	
    			$post_appele = addslashes($tableau["q"]);
    			$destination = addslashes($tableau["r"]);
    			if($tableau["t"]=="numéros spéciaux"){$id_juridiction = "s";}
    			else{$id_juridiction = addslashes(substr($tableau["t"],0,1));}
    			$montant_appel = str_replace(",",".",addslashes($tableau["u"]));
     
    			$requete_appels = "insert into appels values(";
    			$requete_appels .= "null,";
    			$requete_appels .= "'".$poste_appelant."',";
    			$requete_appels .= "'".$id_juridiction."',";
    			$requete_appels .= "'".$numero_facture."',";
    			$requete_appels .= "'".$date_appel."',"; 
    			$requete_appels .= "'".$heure_appel."',";
    			$requete_appels .= "'".$unites_facturees."',";
    			$requete_appels .= "'".$unites_appel."',";
    			$requete_appels .= "'".$montant_appel."',";
    			$requete_appels .= "'".$post_appele."',";
    			$requete_appels .= "'".$destination."',";
    			$requete_appels .= "'0')";
     
    			$insert = mysql_query($requete_appels, $cxn) or die(mysql_error());
    }
    echo 'cpt  : '.$cpt;
    //
    exit(); // On stop tout ici
    ?>
    Tout content je modifie mon fichier original, je fais l'appel du fichier via ma petite interface, le traitement ce passe bien, mais dans ma table 'appels' j'ai le double.

    il doit donc y avoir un double appel quelque part ailleurs, j'ai exécuté mon fichier original à part et tout ce passe bien ... bref perte de temps surement pour une erreur de syntaxe je vais chercher .

  12. #12
    Membre Expert Avatar de RunCodePhp
    Profil pro
    Inscrit en
    Janvier 2010
    Messages
    2 962
    Détails du profil
    Informations personnelles :
    Localisation : Réunion

    Informations forums :
    Inscription : Janvier 2010
    Messages : 2 962
    Par défaut
    Tout content je modifie mon fichier original, je fais l'appel du fichier via ma petite interface, le traitement ce passe bien, mais dans ma table 'appels' j'ai le double.
    Et bien justement, c'était le but.
    Te précipite, pas, fait les trucs en douceurs.

    Quand on patauge comme ça, dès fois c'est plus compliquer de chercher une erreur de manière logique, alors qu'en appliquant presque bêtement (je bien presque) une méthode simple, ça marche.
    La méthode de remettre le code petit à petit, ça marche.

    Ici, comme tu as pris l'initiative de repartir sur une nouvelle page, et bien continu, et réintègre les codes dans celle ci morceau par morceau.
    Tu vas finir par tomber sur celui qui crée provoque doublon.

    A tout hasard quand même, rajoute ceci, sait on jamais :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    $tableau = array();
    while ($tableau = mysql_fetch_array($rs_import)) {
    Et puis surtout, change les noms de tes variables si ce ne sont pas les mêmes, il y a peut être un phénomène de concaténation.
    (tu réutilise souvent les mêmes)
    Comme utiliser une même ressource (comme $resultat) dans des requêtes qui n'ont aucun rapport, ça peu avoir une cause à effet, qui sait.
    Quitte à faire des unset($variable) si elles ne sont plus exploitées plus loin.

    Aussi, tu pourrais exploiter directement le tableau $tableau au lieu de créer à chaque fois des variables :
    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
     
    $tableau = array();
    while ($tableau = mysql_fetch_array($rs_import)) {
    	$numero_facture = mysql_real_escape_string($tableau["c"]);
    	$compte_facturation = mysql_real_escape_string($tableau['a']);
    	$date_facture = mysql_real_escape_string($tableau['d']);
    	//
    	$requete_appels = "INSERT INTO appels VALUES (NULL,
    	'".mysql_real_escape_string($tableau['j']."',
    	'".( ($tableau['t']=='numéros spéciaux') ? 's': mysql_real_escape_string(substr($tableau['t'],0,1)) )."',
    	'".mysql_real_escape_string($tableau['c']."',
    	'".date('Y-m-d',strtotime(substr($tableau['l'],3,2).'/'.substr($tableau['l'],0,2).'/'.substr($tableau['l'],6,4)))."',
    	'".mysql_real_escape_string($tableau['m'])."',
    	'".mysql_real_escape_string($tableau['n'])."',
    	'".mysql_real_escape_string($tableau['o'])."',
    	'".str_replace(",",".",mysql_real_escape_string($tableau['u']))."',
    	'".mysql_real_escape_string($tableau['q'])."',
    	'".mysql_real_escape_string($tableau['r'])."', '0')";
    	$insert = mysql_query($requete_appels, $cxn) or die(mysql_error());
    }
    Puis j'ai remplacer les addslashes() à la place des mysql_real_escape_string, celle ci est faite pour ça.
    Théoriquement tu as besoin que de 3 variables ($numero_facture, $compte_facturation, $date_facture).

  13. #13
    Membre du Club
    Profil pro
    Inscrit en
    Juillet 2009
    Messages
    10
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2009
    Messages : 10
    Par défaut
    Bonjour, c'est un grand jour problème résolu

    après avoir passé toute la fin de journée et début de matinée à faire des tests dans tous les sens je me suis penché sur l'appel de ma page 'traitement_import.php':

    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
    <body>
     
    <table width="100%" border="0">
      <tr> 
        <td height="103" colspan="6" align="center"><img src="images/bandeau.gif" width="70%" height="67"></td>
      </tr>
      <tr> 
       [ . . . ]
     
        <td width="16%" align="center"><a href="traitement_import.php" target="principal"><button>Traitement</button></a></td>
     
       [ . . . ]
      </tr>
    </table>
    </body>
    J'ai simplement enlevé le 'button' ne laissant donc que le lien.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    <td width="16%" align="center"><a href="traitement_import.php" target="principal">Traitement</a></td>
    et là oh miracle tous mes imports dans la table 'appels' se font à la perfection avec le bon nombre de lignes entrées.

    Question pourquoi ce <button>Traitement</button> me provoquait une telle aberration ??

  14. #14
    Membre Expert Avatar de RunCodePhp
    Profil pro
    Inscrit en
    Janvier 2010
    Messages
    2 962
    Détails du profil
    Informations personnelles :
    Localisation : Réunion

    Informations forums :
    Inscription : Janvier 2010
    Messages : 2 962
    Par défaut
    C'est vicelard comme bug

    Question pourquoi ce <button>Traitement</button> me provoquait une telle aberration ??
    Il y a pas si longtemps, un membre (Sabotage il me semble) évoquait un bug d'une version (antérieur) de FireFox.
    Peut être est le cas ?
    J'en sais fichtre rien.

    En tout cas, en peu de temps ça fait 2 fois que quelqu'un évoque un problème de doublon particulièrement étrange.

    Ca me parais improbable, du moins, qu'il soit à l'origine du problème, d'accord, ou pourquoi pas, mais de là qu'il provoquerait le doublon, pas possible.
    Le bouton c'est du HTML, donc coté client, et l'insertion c'est fait du coté serveur (Php, MySQL).
    C'est quand même pas la même chose.

    La seule explication que je donnais à ce bug, c'est qu'il provoquerait 2 appels à la même page.
    Pure hypothèse évidemment.
    Ceci veut dire qu'il y aurait une vérification qui échouerait au niveau du Php, ce qui fait que les données seraient enregistrées/cumulées 2 fois.


    Si ça tenait qu'à moi, je laisserait le bug, donc le bouton, et chercherais à éviter ce doublon coté Php ou MySQL.
    Il doit être possible de l'éviter à ce niveau, c'est pas possible, tu ne crois pas ?.


    Question comme ça.
    Avait tu laissé le point d'arrêt, le exit() en sortie de la boucle?

  15. #15
    Membre du Club
    Profil pro
    Inscrit en
    Juillet 2009
    Messages
    10
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2009
    Messages : 10
    Par défaut
    Si ça tenait qu'à moi, je laisserait le bug, donc le bouton, et chercherais à éviter ce doublon coté Php ou MySQL.
    Il doit être possible de l'éviter à ce niveau, c'est pas possible, tu ne crois pas ?.
    Je suis d'accord mais comme je suis en stage et que j'ai perdu pas mal de temps je chercherai sur mon temps libre.
    Mon maitre de stage ne comprenant lui non plus ce bug, il penche aussi sur 2 appels mais reste étonné de ce comportement.

    il me faudra de toute façon trouver car cela peut être intéressant lors de mon oral d'évoquer ce bug si il est réellement pertinent .

  16. #16
    Membre Expert Avatar de RunCodePhp
    Profil pro
    Inscrit en
    Janvier 2010
    Messages
    2 962
    Détails du profil
    Informations personnelles :
    Localisation : Réunion

    Informations forums :
    Inscription : Janvier 2010
    Messages : 2 962
    Par défaut
    Dans ces conditions, il est compréhensible qu'il ne faille pas y passer des semaines.

    C'est pas dit que c'est un bug, mais ce qui est certain, c'est que le comportement est pour le moins surprenant.

    Je n'ai jamais remarqué ou rencontré une telle situation.
    Je tenterais plus tard de reprendre ton même principe/code (formulaire + <bouton></bouton) et une insertion.
    En somme, c'est de pouvoir reproduire le même comportement.


    Hormis ce problème de bug, un bouton à l'intérieur d'un lien, ça na pas de sens théoriquement.
    Je ne sais pas comment dire ça, mais ce n'est pas correcte au niveau de la sémantique (si on peu dire).
    Un lien à coté d'un bouton, là, d'accord.


    Ceci d'ailleurs, pourrait expliquer, ou mener vers un double appel à la même page, qui sait.
    Si double appel il y a, il peu avoir moyen de le savoir avec une variable de session, en l'incrémentant.

Discussions similaires

  1. Problème avec des insertions massives dans un ldap
    Par felix79 dans le forum Développement
    Réponses: 0
    Dernier message: 08/07/2011, 12h00
  2. problème des insertions automatiques "."
    Par clem12345 dans le forum Eclipse PHP
    Réponses: 1
    Dernier message: 17/04/2009, 14h18
  3. Problème avec l'insertion des trees !
    Par levenimeux dans le forum Langage
    Réponses: 1
    Dernier message: 05/06/2007, 09h37
  4. Réponses: 3
    Dernier message: 10/05/2007, 10h42
  5. [C#] problème avec l'insertion des données dans MySQL
    Par madica dans le forum Accès aux données
    Réponses: 7
    Dernier message: 08/11/2005, 13h27

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