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

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  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.

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