[RESOLU] Eviter 2 fois la meme insertion en bdd

Eléphant du PHP | 372 Messages

12 oct. 2015, 22:40

Salut je rentre en bdd un fichier csv mais il peut que certaines entrée soit en double mais avec un numéro unique.
J'ai donc déjà une grande partie en bdd et la je voudrais relancer mon script pour faire ma mise a jour avec les nouvelles données
mais je souhaite faire un truc du genre si le numéro existe déjà en bdd alors tu ne fait rien si il n'existe pas alors insertion en bdd.

Le problème est qu'il ré insert tout a chaque fois :/
// Récupération des données
	$number = addslashes($item->number);
    $titre = addslashes($item->name);
// bla bla

		$result = mysql_query("SELECT number FROM matable WHERE number = ".$number."");
	if(mysql_num_rows($result) == 1){
		
	//Entrée déjà existante
	echo 'Cette entrée existe déjà';
	
	}else{
		
	// Pseudo libre
	 $sql = "INSERT INTO `matable` (id_simply_user,titre,...,...,) VALUES ('$id_simply_user','$titre','$...','$...')";
  $req = mysql_query($sql) or die('Erreur SQL !'.$sql.'<br>'.mysql_error());
  echo 'Insertion en bdd';
	}
	}
?>

Mammouth du PHP | 2703 Messages

12 oct. 2015, 22:51

quel est le type du champ number de la table matable ?

Eléphant du PHP | 372 Messages

12 oct. 2015, 22:55

varchar(10)

Eléphant du PHP | 372 Messages

12 oct. 2015, 23:43

Bon j'ai changer ma requete pour voir mais ça ne change rien, voilà ou j'en suis:
$result = mysql_query("SELECT number FROM table WHERE number='".$number."");
	if(mysql_num_rows($result) == 1){
		
	//Entrée déjà existante
	echo 'Cette entrée existe déjà';
	
	}else{
		
	// Pseudo libre
	 $sql = "INSERT INTO `table` (id_simply_user,titre,number,valide) VALUES ('$id_simply_user','$titre','$number','$valide')";
  $req = mysql_query($sql) or die('Erreur SQL !'.$sql.'<br>'.mysql_error());
  echo 'Insertion en bdd';
	}
	}
	
?>

Avatar du membre
Modérateur PHPfrance
Modérateur PHPfrance | 10684 Messages

13 oct. 2015, 09:28

Bonjour,

Si le script exécute l'insertion, c'est la condition du if() est fausse. peut être que le nombre d'enregistrements présents en base pour lesquels la colonne number est égale à la valeur cherchée est-il supérieur à 1...

Essayes avec " if (mysql_num_rows($result) > 0) { ", ça t'enlèvera déjà ce genre de problème :)

Une autre solution serait d'ajouter une clé primaire/unique sur ta colonne number de façon à ce que si tu tentes d'en insérer un second, c'est la base de données qui va te renvoyer une erreur (c'est moins "propre" que de vérifier si tu as le droit d'insérer avant de le faire, mais la gestion de l'erreur permet parfois d'améliorer les performances)
Ce n'est pas en améliorant la bougie que l'on a inventé l'ampoule...

Eléphant du PHP | 372 Messages

13 oct. 2015, 15:43

Donc me revoilà, j'ai changer ce que tu mas dis mais ça re rentre toujours les mêmes infos .... alors que le "number" existe déjà
et si je met une clé unique direct en bdd mon script plante et j'ai besoin de passer par un script ...
Du coup je ne met que l'essentiel du code si quelqu'un voit le problème , merci à vous .
// connexion à la base

 $type  = array(     // Concert  
                        'POP|Pop-rock/Folk' => 10, '11P|Pop-Rock/Musique électronique' => 10, '1MC|Musique/Concerts' => 10, 'VAI|Variété internationale' => 10, 'VAI|Variété internationale ' => 10, 'VAF|Variété et chanson françaises' => 10,
                        'CMU|Comédie Musicale' => 10, 'HAR|Hard-rock/Métal' => 10,  'MEL|Musique électronique' => 10,  'CLU|Clubbing & Soirées' => 10, 'SOI|Galas/Soirées étudiante' => 10,
                        );

// Ca continue ...
 
     
	
	                       
    // On entre les entrees en bdd 
	function multiexplode ($delimiters,$string) {
   
    $ready = str_replace($delimiters, $delimiters[0], $string);
    $launch = explode($delimiters[0], $ready);
    return  $launch;
	}                
    foreach ($flux->product as $item) {
		

    // Récupération des données en fonction du tagname du XML
	$number = addslashes($item->number);
    $titre = addslashes($item->name);
    $price = $item->price;
	//
	// Quelques variables ....
     
    // On valide par default
    $valide = '1';
	
	

	foreach (explode(' ; ', /*(string)*/ $item->merchantCategoryPath) as $subtype) {
	$id_type_loisirs = $type[$subtype];
	
	}  
	
		// Association de la description en fonction du type de sorties
	
		$assoc_concert = 'Votre concert avec '.$titre.'.</a> ';
		
		if ($id_type_loisirs == 10) {
			$desc_genre = $assoc_concert; // Concert
		} elseif ($id_type_loisirs == 11) {
			$desc_genre = $assoc_spectacle; // Spectacle
	
		}
	
		// description
		$description = addslashes($desc_genre);

		$result = mysql_query("SELECT id FROM tableWHERE number = ".$number."");
	if (mysql_num_rows($result) > 0) { 
		
	//Entrée déjà existante
	echo 'Cette entrée existe déjà';
	
	}else{
		
	// Pseudo libre
	 $sql = "INSERT INTO `table` (id_simply_user,titre,price,photo) VALUES ('$id_simply_user','$titre','$price','$photo')";
  $req = mysql_query($sql) or die('Erreur SQL !'.$sql.'<br>'.mysql_error());
  echo 'Insertion en bdd';
	}
	}
	
	
	
	
	
	
?>

Avatar du membre
Modérateur PHPfrance
Modérateur PHPfrance | 10684 Messages

13 oct. 2015, 16:53

En l'état, ta requête :
$result = mysql_query("SELECT id FROM tableWHERE number = ".$number."");
doit retourner une erreur à l'exécution car il te manque un espace entre "table" et "WHERE". Il ne rentrera donc pas dans le if() mais exécutera systématiquement le else.

A noter par ailleurs que "table" est un mot clé réservé du langage SQL et qu'il ne doit donc pas être utiliser comme nom de table ou de colonne... :)
Ce n'est pas en améliorant la bougie que l'on a inventé l'ampoule...

Eléphant du PHP | 372 Messages

13 oct. 2015, 17:23

Voilà quelque chose de + claire surement ( j'ai essayer de réduire le code au mieux )
// connexion ...

 
    $type  = array(     // Concert  
                        'POP|Pop-rock/Folk' => 10, '11P|Pop-Rock/Musique électronique' => 10, '1MC|Musique/Concerts' => 10, 'VAI|Variété internationale' => 10, 'VAI|Variété internationale ' => 10, 'VAF|Variété et chanson françaises' => 10,
                        'CMU|Comédie Musicale' => 10, 'HAR|Hard-rock/Métal' => 10,  'MEL|Musique électronique' => 10,  'CLU|Clubbing & Soirées' => 10, 'SOI|Galas/Soirées étudiante' => 10,
                         // Cinéma
                         'FIL|Film' => 18, 'ACI|Abonnement/Pass cinéma' => 18, 'ACT|Action' => 18, 'ANI|Animation' => 18, 'ARM|Arts martiaux' => 18, 'AVE|Aventure' => 18, 'AVP|Avant-première' => 18, 'BIO|Biopic' => 18, 'BOL|Bollywood' => 18, 'CIC|Ciné-concert' => 18,
                         'CIE|Cinéma jeune public' => 18, 'CLA|Classique' => 18, 'COD|Comédie dramatique' => 18, 'COM|Comédie' => 18, 'DEA|Dessin animé' => 18, 'DIV|Divers' => 18, 'DOC|Documentaire' => 18, 'DRA|Drame' => 18, 'EPO|Epouvante-horreur' => 18, 'ERO|Erotique' => 18,
                         'ESP|Espionnage' => 18, 'FAN|Fantastique ' => 18, 'FCE|Comédie érotique' => 18, 'FFA|Famille' => 18, 'GUE|Guerre' => 18, 'HIS|Historique' => 18, 'JUD|Judiciaire' => 18, 'MED|Médical' => 18, 'MOB|Mobisode' => 18, 'MUS|Musical' => 18,
                         'NUI|Nuit à thème (cinéma)' => 18, 'PEP|Péplum' => 18,  'POL|Policier' => 18, 'ROM|Romance' => 18, 'SCF|Science fiction' => 18, 'SOA|Soap' => 18, 'THR|Thriller' => 18,
                         'WEB|Web série' => 18, 'WES|Western' => 18, '131F|Cinéma' => 18,  '13CI|Cinéma' => 18, 'ROC|Retransmission Opéra/Concert ;' => 18, 'ROC|Retransmission Opéra/Concert;' => 18, '81F|Cinéma' => 18, '8CI|Cinéma' => 18,
                        );
 
     
	
	                       
    // On entre les entrees en bdd 
	function multiexplode ($delimiters,$string) {
   
    $ready = str_replace($delimiters, $delimiters[0], $string);
    $launch = explode($delimiters[0], $ready);
    return  $launch;
	}                
    foreach ($flux->product as $item) {
		

    // Récupération des données en fonction du tagname du XML
	$number = addslashes($item->number);
    $titre = addslashes($item->name);

      $postcode  = addslashes($item->extra2);
      $pieces = explode(" | ", $postcode);
	
	  // on parcourt le tag longDescription du XML
	  $longDescription = addslashes($item->longDescription);
	  $decoupe = multiexplode(array("|"," ","|"," "),$longDescription);
	  
	  // Début événement
	  $dateDebut = $decoupe[0];
	  $heureDebut = $decoupe[1];
	  $dateFin = $decoupe[2];
	  $heurefin = $decoupe[3];
	  
	  
	    //conversion de la date debut du format fr(jj:mm:aaaa hh:mm:ss) en format us(aaaa-mm-jj hh:mm:ss)
	  $dateDebut = date_create_from_format('d/m/Y',$dateDebut);
	  $dateDebut = date_format($dateDebut, 'Y-m-d');
	  
	  
	
    // On valide la sortie par default
    $valide = '1';
	
	

	foreach (explode(' ; ', /*(string)*/ $item->merchantCategoryPath) as $subtype) {
	$id_type_loisirs = $type[$subtype];
	
	}  
	
		
		if ($id_type_loisirs == 10) {
			$desc_genre = $assoc_concert; // Concert
		} elseif ($id_type_loisirs == 11) {
			$desc_genre = $assoc_spectacle; // Spectacle
		}
	
		// description
		$description = addslashes($desc_genre);

		$result = mysql_query("SELECT id_loisirs FROM loisirs WHERE number = ".$number."");
	if (mysql_num_rows($result) > 0) { 
		
	//Entrée déjà existante
	echo 'Cette entrée existe déjà';
	
	}else{
		
	//  libre
	 $sql = "INSERT INTO `loisirs` (id_simply_user,titre,price,photo,url_fnac,date_debut_sortie,horaire_debut,date_fin_sortie,horaire_fin,description,street,postcode,city,id_region,id_departements,id_type_loisirs,number,valide) VALUES ('$id_simply_user','$titre','$price','$photo','$url_fnac','$date_debut_sortie', '$heureDebut', '$date_fin_sortie', '$heurefin', '$description','$street','$pieces[0]','$pieces[1]','$region','$departement','$id_type_loisirs','$number','$valide')";
  $req = mysql_query($sql) or die('Erreur SQL !'.$sql.'<br>'.mysql_error());
  echo 'Insertion en bdd';
	}
	}

?>

Mammouth du PHP | 2703 Messages

13 oct. 2015, 17:53

$sql = "SELECT id_loisirs FROM loisirs WHERE number = ".$number."";
echo $sql;
$result = mysql_query($sql);

tu exécutes ce que tu obtiens dans phpmyadmin et tu vérifies que cela aboutisse bien à ce que tu souhaites.

Avatar du membre
Modérateur PHPfrance
Modérateur PHPfrance | 10684 Messages

13 oct. 2015, 17:55

Si number est un varchar en base, alors sa valeur devrait être délimitée par des apostrophes :
$result = mysql_query("SELECT id_loisirs FROM loisirs WHERE number = '".$number."'");
Pour simplifier le debugage, je te recommande de stocker ta requête dans une variable. Tu pourras ainsi facilement l'afficher avec un echo pour voir ce que tu envoi à mysql :
$sql = "SELECT id_loisirs FROM loisirs WHERE number = '".$number."'";
$result = mysql_query($sql);
Si tu ajoutes un echo $sql, tu verras la requête générée et tu pourras l'exécuter directement dans MySQL afin de voir le résultat. Ca sera ainsi plus facile de comprendre le comportement de php quand il reçoit celui-ci. Et je viens de voir que tu le fais déjà juste après pour l'insertion, alors autant le généraliser :)

De même, tu peux ajouter un or die(mysql_error()) pour t'assurer de la bonne exécution du SELECT ;)
Ce n'est pas en améliorant la bougie que l'on a inventé l'ampoule...

Eléphant du PHP | 372 Messages

14 oct. 2015, 20:56

En supprimant mon insert pour faire uniquement un echo de ma req le tout plante a chaque fois et oui mon champ number est bien VARCHAR j'ai donc fait comme tu ma dis mais cela ne change rien. Je désespère ...

Avatar du membre
Modérateur PHPfrance
Modérateur PHPfrance | 10684 Messages

15 oct. 2015, 12:10

Si tu affiches la variable $sql avec le SELECT, est-ce que la requête te parait cohérente ? est-ce que si tu l'exécutes directement sur ta base de données MySQL tu obtiens des résultats ?

Si tu remplaces la fin de ton code par ceci, qu'est ce qui est affiché à l'écran ?
$sql = "SELECT id_loisirs FROM loisirs WHERE number = '".$number."'";
$result = mysql_query($sql)  or die('Erreur SQL ! ' . $sql . '<br>' . mysql_error());

$nbResult = mysql_num_rows($result);

if ($nbResult > 0) {   //Entrée déjà existante
  echo '"' . $number. '" existe déjà en ' . $nbResult . ' exemplaire(s)';
} else { //  libre
  echo '"' . $number. '" inexistant, insertion en bdd à réaliser';
}
Ce n'est pas en améliorant la bougie que l'on a inventé l'ampoule...

Eléphant du PHP | 372 Messages

15 oct. 2015, 18:07

On doit pas etre bien loin du compte
ca marche apparament mais ca n'insère q'une ligne il manque une accolade ?
Suis je aveugle à ce point ?
// description
		$description = addslashes($desc_genre);
	}
		
		$sql = "SELECT id_loisirs FROM loisirs WHERE number = '".$number."'";
$result = mysql_query($sql)  or die('Erreur SQL ! ' . $sql . '<br>' . mysql_error());

$nbResult = mysql_num_rows($result);

if ($nbResult > 0) {   //Entrée déjà existante
  echo '"' . $number. '" existe déjà en ' . $nbResult . ' exemplaire(s)';
} else { //  libre
  // Pseudo libre
	 $sql = "INSERT INTO `loisirs` (id_simply_user,titre,price,photo,url_fnac,date_debut_sortie,horaire_debut,date_fin_sortie,horaire_fin,description,street,postcode,city,id_region,id_departements,id_type_loisirs,number,valide) VALUES ('$id_simply_user','$titre','$price','$photo','$url_fnac','$date_debut_sortie', '$heureDebut', '$date_fin_sortie', '$heurefin', '$description','$street','$pieces[0]','$pieces[1]','$region','$departement','$id_type_loisirs','$number','$valide')";
  $req = mysql_query($sql) or die('Erreur SQL !'.$sql.'<br>'.mysql_error());
  echo 'Insertion en bdd';
}
	

	
?>

Eléphant du PHP | 372 Messages

15 oct. 2015, 18:20

oups c'est bon j'ai trouver, merci encore ;)