Précédent   Forum des professionnels en informatique > PHP > PHP & SGBD > PHP & MySQL
PHP & MySQL Forum d'entraide sur les fonctions MySQL avec PHP. Avant de poster -> FAQ MySQL, Cours MySQL et Sources MySQL. Pour les questions concernant le moteur MySQL plutôt que les fonctions PHP, merci d'utiliser le forum MySQL.
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 05/06/2011, 18h03   #1
Invité de passage
 
Homme
Inscription : mai 2011
Messages : 13
Détails du profil
Informations personnelles :
Sexe : Homme

Informations forums :
Inscription : mai 2011
Messages : 13
Points : 1
Points : 1
Par défaut LOAD DATA INFILE qui fonctionne à moitié

Bonjour,

Je suis confronté à un problème qui me prend la tête et que je ne réussi pas à résoudre, j'espère donc trouver une réponse sur ce forum.

Je veux insérer dans ma base de donnée un grand nombre de ligne (plus de 3000) venant d'un fichier texte.
J'ai donc trouver le saint graal : LOAD DATA INFILE.
Seulement, il y a des caractères spéciaux dans ce fichier, tel que "&" et et les simples quote, et lors de mes requêtes suivantes j'ai des messages d'erreurs (ben oui, le simple quote me ferme ma requête, car il n'a pas été échappé avec un antislash).

Voici mon code actuel, qui fait bien l'ajout dans la table temp et qui permet de remplir les autres tables, mais dès que je rajoute la ligne commenter (celle du FIELDS ESCAPED BY), plus rien ne fonctionne (et pourtant je n'ai aucun message d'erreur).

Code :
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
 
/// Fonction connexion à la BDD
	function connexion_bdd() {
		try {
			$pdo_options[PDO::ATTR_ERRMODE] = PDO::ERRMODE_EXCEPTION;
			if ($_SERVER["SERVER_NAME"] == "localhost" || $_SERVER["SERVER_NAME"] == "127.0.0.1") {
				$bdd = new PDO('mysql:host=localhost;dbname=xxxxxxx', 'xxxxxxx', 'xxxxxx', $pdo_options);
			}
			else {
				$bdd = new PDO('mysql:host=mysql51-34.bdb;dbname=xxxxxxxx', 'xxxxxx', 'xxxxxxx', $pdo_options);
			}
		}
		catch(Exception $e) {
			die('Erreur : '.$e->getMessage());
		}
		return $bdd;
	}
 
 
/// Partie du fichier pour la MAJ de la BDD
				$bdd = connexion_bdd();
 
				$req = "TRUNCATE TABLE temp; ";
				if ($_SERVER["SERVER_NAME"] == "localhost" || $_SERVER["SERVER_NAME"] == "127.0.0.1") {
					$req .= "LOAD DATA INFILE 'SITE_utf8.txt' ";
				}
				else {
					$req .= "LOAD DATA LOCAL INFILE 'SITE_utf8.txt' ";
				}
				$req .= "REPLACE INTO TABLE temp ";
 
////////////////////////////////////// Cette ligne !!!!
				$req .= "FIELDS ESCAPED BY '\\' ";
 
				$req .= "IGNORE 1 LINES ;";
				$bdd->query($req);
 
				$bdd->query("TRUNCATE TABLE categories;");
				$req_categories = "INSERT INTO categories (groupe_produit, cat, sub_cat) SELECT DISTINCT num_groupe, cat, sub_cat FROM temp;";
				$reponse_categories = $bdd->query($req_categories);
 
				$bdd->query("TRUNCATE TABLE articles;");
				$req_articles = "INSERT INTO articles (num, description, groupe, life_cycle_code) SELECT num_art, description, num_groupe, life_cycle_code FROM temp;";
				$reponse_articles = $bdd->query($req_articles);
 
				// On vide la table temporaire
				$bdd->query("TRUNCATE TABLE temp;");
 
				echo 'Mise à jour des tables "categories" et "articles" effectué !';
Merci d'avance pour vos réponses,

TheDeadMan
thedeadman est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 05/06/2011, 18h45   #2
Modérateur
 
Inscription : septembre 2010
Messages : 7 103
Détails du profil
Informations forums :
Inscription : septembre 2010
Messages : 7 103
Points : 8 466
Points : 8 466
comment est crée le SITE_utf8.txt ?
__________________
http://blog.stealth35.com/
stealth35 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 05/06/2011, 19h16   #3
Invité de passage
 
Homme
Inscription : mai 2011
Messages : 13
Détails du profil
Informations personnelles :
Sexe : Homme

Informations forums :
Inscription : mai 2011
Messages : 13
Points : 1
Points : 1
C'est vrai que j'aurais du le préciser dans mon premier message.

Ce fichier est crée par SAP, suite à un requête SQL toute bête.
En fait, le résultat s'affiche dans une fenêtre sous la forme d'une table, et la seule chose que l'on peut faire c'est "fichier/exporter", aucun réglage possible...

D'ailleurs, ça me pose problème concernant l'encodage, SAP encodant le fichier en UTF-16... je suis obligé de passer par Notepad++ et de le convertir en UTF-8 (si quelqu'un à une solution automatisé en passant par Php, merci !)

Voici les premières lignes du fichier :
Code :
1
2
3
4
5
6
7
#	Numéro	CATEGORIE	SOUS-CATEGORIE	Numéro d'article	Description article	LifeCycleCode	
1	496	Univers Ludique	Accessoires Bois	700104	LOT  2 PACKS DE 24 BOITES ASSORTIES	N11	
2	496	Univers Ludique	Accessoires Bois	700105	LOT  2 PACKS DE 12 JEUX ASSORTIS	N11	
3	496	Univers Ludique	Accessoires Bois	700106	LOT 10 CARNETS CHEVALIERS GM	N11	
4	496	Univers Ludique	Accessoires Bois	700107	LOT 10 CARNETS CHEVALIERS PM	N11	
5	496	Univers Ludique	Accessoires Bois	700108	LOT 10 REGLES BOIS CHEVALIERS	N11	
6	496	Univers Ludique	Accessoires Bois	700109	LOT 10 CARNETS PRINCESSES GM	N11
thedeadman est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 05/06/2011, 19h19   #4
Modérateur
 
Inscription : septembre 2010
Messages : 7 103
Détails du profil
Informations forums :
Inscription : septembre 2010
Messages : 7 103
Points : 8 466
Points : 8 466
si t'as des caractère spéciaux dans ton CSV et que SAP ne les échappes pas, ca va être difficile puisque le CSV n'est pas valide

pour le charset utilise l'option CHARACTER SET
__________________
http://blog.stealth35.com/
stealth35 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 05/06/2011, 20h01   #5
Invité de passage
 
Homme
Inscription : mai 2011
Messages : 13
Détails du profil
Informations personnelles :
Sexe : Homme

Informations forums :
Inscription : mai 2011
Messages : 13
Points : 1
Points : 1
Hum, pour le character set, je fais "... INTO TABLE TEMP CHARACTER SET utf8" ? (je peux pas tester ce soir).

Par contre, pour les caractères spéciaux, je comprends pas, ce n'est justement pas le rôle du ESCAPED BY '\' d'échapper les caractères spéciaux s'il en trouve ?

Sinon, il faudrait analyser le fichier caractère par caractère (ou ligne par ligne, mais la faut trouver les fonctions adéquates) et ajouter un / avant chaque caractère spéciaux.
Peut être chercher du côté des regex ?
thedeadman est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 05/06/2011, 20h25   #6
Membre Expert
 
Inscription : septembre 2010
Messages : 1 242
Détails du profil
Informations forums :
Inscription : septembre 2010
Messages : 1 242
Points : 1 564
Points : 1 564
Citation:
Envoyé par thedeadman Voir le message
Par contre, pour les caractères spéciaux, je comprends pas, ce n'est justement pas le rôle du ESCAPED BY '\' d'échapper les caractères spéciaux s'il en trouve ?
Je pense plutôt que c'est pour spécifier comment les caractères ont été échappés dans le document original.
__________________
- Réalisations
- Interface graphique : génération en javascript d'objets défilants, texte et/ou images, mode horizontal ou vertical.
ABCIWEB est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 05/06/2011, 20h55   #7
Modérateur
 
Inscription : septembre 2010
Messages : 7 103
Détails du profil
Informations forums :
Inscription : septembre 2010
Messages : 7 103
Points : 8 466
Points : 8 466
le caractère échappement c'est uniquement quand la chaine contient le séparateur de champs ou de lignes
__________________
http://blog.stealth35.com/
stealth35 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 05/06/2011, 21h07   #8
Invité de passage
 
Homme
Inscription : mai 2011
Messages : 13
Détails du profil
Informations personnelles :
Sexe : Homme

Informations forums :
Inscription : mai 2011
Messages : 13
Points : 1
Points : 1
Ok, je l'avais pas compris comme ça... maintenant je comprends pourquoi ça fonctionné pas...

Je vais donc devoir passer par un autre moyen, que pensez-vous de mes propositions ? Ça prendra pas trop de temps ?

Citation:
Sinon, il faudrait analyser le fichier caractère par caractère (ou ligne par ligne, mais la faut trouver les fonctions adéquates) et ajouter un / avant chaque caractère spéciaux.
Peut être chercher du côté des regex ?
thedeadman est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 05/06/2011, 21h19   #9
Modérateur
 
Inscription : septembre 2010
Messages : 7 103
Détails du profil
Informations forums :
Inscription : septembre 2010
Messages : 7 103
Points : 8 466
Points : 8 466
montre plutôt une ligne qui ne fonctionne pas,
__________________
http://blog.stealth35.com/
stealth35 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 05/06/2011, 22h10   #10
Invité de passage
 
Homme
Inscription : mai 2011
Messages : 13
Détails du profil
Informations personnelles :
Sexe : Homme

Informations forums :
Inscription : mai 2011
Messages : 13
Points : 1
Points : 1
Par exemple, avec la ligne :

Code :
1263	145	Décoration	Maison d'autrefois	280439	LOT 4 HORLOGES MARGAUX	N10
j'ai, lors du listage de toute les catégories :

Code :
Fatal error: Uncaught exception 'PDOException' with message 'SQLSTATE[42000]: Syntax error or access violation: 1064 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 'autrefois' AND groupe_produit=groupe' at line 1' in /xxxxxx/xxxx/xxxxx/client_categories.php:76 Stack trace: #0 /homez.428/enescofr/enescofr/client_categories.php(76): PDO->query('SELECT num FROM...') #1 {main} thrown in /xxx/xxxx/xxxxx/client_categories.php on line 76
ou par exemple la catégorie "Chick & Fun", j'ai bien ce libellé qui s'affiche, mais lorsque je rentre dans la catégorie, je n'ai que Chick qui apparait (et évidemment, lorsque je rentre dans la requête cherchant les produits de la catégorie "Chick" ne mêne à rien, car cette catégorie n'existe pas).

Mais ça je viens de comprendre, c'est parce que je passe la catégorie et la sous catégorie en Get, le & foire donc tout, il faut que je le transforme lors de l'affichage du lien (je pense qu'après la requête fonctionnera).

Ce qui laisse le problème des quotes, quelles soit simple ou double (je crois avoir vu des doubles dans le fichier).

Par ailleurs, totalement HS, j'ai des photos des articles qui doivent être affichés, et je voudrais créer des miniatures.
J'ai bien un script qui fonctionne, mais déjà rien que pour redimensionner 5 images ça devait mettre 15sec, alors qu'en fait j'en ai autant que le nombre d'article à redimensionner, soit plus de 3000.
Une idée ?
thedeadman est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 05/06/2011, 23h35   #11
Membre Expert
 
Inscription : septembre 2010
Messages : 1 242
Détails du profil
Informations forums :
Inscription : septembre 2010
Messages : 1 242
Points : 1 564
Points : 1 564
Citation:
Envoyé par thedeadman Voir le message
Par ailleurs, totalement HS, j'ai des photos des articles qui doivent être affichés, et je voudrais créer des miniatures.
J'ai bien un script qui fonctionne, mais déjà rien que pour redimensionner 5 images ça devait mettre 15sec, alors qu'en fait j'en ai autant que le nombre d'article à redimensionner, soit plus de 3000.
Une idée ?
Le plus simple est de charger les fichiers sur ton ordinateur puis de redimensionner les photos avec un traitement par lots dans un logiciel photo (il faudra peut-être faire plusieurs lots).

Sinon en php tu vas vite être limité par le temps limite autorisé pour ton script (à moins aussi de le faire en local auquel cas tu peux modifier ce paramètre assez facilement). Donc il faudra faire des petits lots de x photos et répéter ton script n fois. Si tu ne veux pas déclencher ton script manuellement (300 fois si tu fais des lots de 10 photos), tu pourras utiliser un cron.
__________________
- Réalisations
- Interface graphique : génération en javascript d'objets défilants, texte et/ou images, mode horizontal ou vertical.
ABCIWEB est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 06/06/2011, 09h10   #12
Invité de passage
 
Homme
Inscription : mai 2011
Messages : 13
Détails du profil
Informations personnelles :
Sexe : Homme

Informations forums :
Inscription : mai 2011
Messages : 13
Points : 1
Points : 1
Oui j'ai pensé à ça pour le faire la première fois sur les 3000 images, mais par la suite, le but est d'automatiser tout ça, donc quand il y aura 200 ou 300 nouvelles images il faudra passer par Php, et la ça va coincer quand même...

Sinon, personne a d'idée pour échapper ces *&ù$^* de caractères spéciaux ?
thedeadman est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 06/06/2011, 10h14   #13
Modérateur
 
Inscription : septembre 2010
Messages : 7 103
Détails du profil
Informations forums :
Inscription : septembre 2010
Messages : 7 103
Points : 8 466
Points : 8 466
normalement t'as pas besoin d’échapper les valeurs
t'as essayé avec un simple INSERT en requete préparée
__________________
http://blog.stealth35.com/
stealth35 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 06/06/2011, 10h31   #14
Invité de passage
 
Homme
Inscription : mai 2011
Messages : 13
Détails du profil
Informations personnelles :
Sexe : Homme

Informations forums :
Inscription : mai 2011
Messages : 13
Points : 1
Points : 1
Pourquoi j'aurais pas besoin d'échapper les valeurs ?

J'ai cette requête :

Code :
SELECT num, description, life_cycle_code FROM categories, articles WHERE categories.groupe_produit = articles.groupe AND sub_cat='" . $_GET['sub_categories'] . "';
Avec la sous catégories "Maison d'autrefois", ça donne :

Code :
SELECT num, description, life_cycle_code FROM categories, articles WHERE categories.groupe_produit = articles.groupe AND sub_cat='Maison d'autrefois';
Je n'ai pas essayé en requête préparé, mais j'avais essayé le INSERT, mais sur 3000 lignes ça ne fonctionne pas (trop lent).
Avant l'arrêt du script au bout de 30sec, il n'avait rentré que 300 lignes je crois.
Et je vois pas en quoi passer par un INSERT changera le problème du ' qui n'est pas échappé.
thedeadman est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 06/06/2011, 10h35   #15
Modérateur
 
Inscription : septembre 2010
Messages : 7 103
Détails du profil
Informations forums :
Inscription : septembre 2010
Messages : 7 103
Points : 8 466
Points : 8 466
montre comment tu faisais avec tes 3000 lignes
__________________
http://blog.stealth35.com/
stealth35 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 06/06/2011, 11h58   #16
Invité de passage
 
Homme
Inscription : mai 2011
Messages : 13
Détails du profil
Informations personnelles :
Sexe : Homme

Informations forums :
Inscription : mai 2011
Messages : 13
Points : 1
Points : 1
J'ai pas mal cherché, mais j'ai pas retrouvé.
C'était tellement lent j'ai pas du le garder ^^

En gros, ça faisait ça :

Code :
1
2
3
4
5
6
7
8
 
$f = fopen ("site_UTF8.txt", "r");
while ($line= fgets ($f)) {
	$donnees = explode('\t', $line);
	// Inventé pour l'exemple, mais c'est une requête INSERT quoi
	$bdd->query("INSERT INTO temp num, cat VALUES ('." $donnees[0] ".', '." $donnees[1] ".');");
}
fclose ($f);
Lecture de chaque ligne et ajout grâce à INSERT dans la BDD.
Et c'est ultra lent !
thedeadman est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 06/06/2011, 13h41   #17
Modérateur
 
Inscription : septembre 2010
Messages : 7 103
Détails du profil
Informations forums :
Inscription : septembre 2010
Messages : 7 103
Points : 8 466
Points : 8 466
normale tu fais pas de requête préparée, et pour parsé du CSV c'est fgetcsv pas explode, de plus que le '\t' est faux, ça devait pas faire grand chose
__________________
http://blog.stealth35.com/
stealth35 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 06/06/2011, 13h57   #18
Invité de passage
 
Homme
Inscription : mai 2011
Messages : 13
Détails du profil
Informations personnelles :
Sexe : Homme

Informations forums :
Inscription : mai 2011
Messages : 13
Points : 1
Points : 1
Le explode, c'est pas du tout ce que je faisait, mais je m'en rappelle plus.
Par contre je connaissais pas fgetcsv, merci !

Mais au final, la requête préparé elle va quand même gueuler sur le ' non ?

EDIT : J'ai étudié le fgetcvs, j'ai même utilisé l'exemple :

Code :
1
2
3
4
5
6
7
8
9
10
11
12
$row = 1;
if (($handle = fopen("test.csv", "r")) !== FALSE) {
    while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) {
        $num = count($data);
        echo "<p> $num champs à la ligne $row: <br /></p>\n";
        $row++;
        for ($c=0; $c < $num; $c++) {
            echo $data[$c] . "<br />\n";
        }
    }
    fclose($handle);
}
Ce qui me donne :

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
8 champs à la ligne 2:
1
496
Univers Ludique
Accessoires Bois
700104
LOT 2 PACKS DE 24 BOITES ASSORTIES
N11
 
8 champs à la ligne 3:
2
496
Univers Ludique
Accessoires Bois
700105
LOT 2 PACKS DE 12 JEUX ASSORTIS
N11
Ok, c'est bien beau tout ça, mais ça change quoi ?
Parce que là, je vais mettre tout ça dans ma BDD, mais je le fais déjà actuellement !

Le problème, c'est lorsque l'utilisateur clique sur une sous catégories (elle son listé sur une page), ça affiche tous les produits de cette sous catégories, c'est lors de cette requête que ça plante.

J'ai cette requête :

Code :
SELECT num, description, life_cycle_code FROM categories, articles WHERE categories.groupe_produit = articles.groupe AND sub_cat='" . $_GET['sub_categories'] . "';
Avec la sous catégories "Maison d'autrefois", ça donne :

Code :
SELECT num, description, life_cycle_code FROM categories, articles WHERE categories.groupe_produit = articles.groupe AND sub_cat='Maison d'autrefois';
C'est pour ça que je cherche à échapper ces caractères spéciaux dans le .txt (ou .csv).
thedeadman est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 06/06/2011, 14h22   #19
Modérateur
 
Inscription : septembre 2010
Messages : 7 103
Détails du profil
Informations forums :
Inscription : septembre 2010
Messages : 7 103
Points : 8 466
Points : 8 466
en requete préparé t'as pas besoin d’échappé les caractères, donc fait une requete préparée.
__________________
http://blog.stealth35.com/
stealth35 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 06/06/2011, 14h32   #20
Invité de passage
 
Homme
Inscription : mai 2011
Messages : 13
Détails du profil
Informations personnelles :
Sexe : Homme

Informations forums :
Inscription : mai 2011
Messages : 13
Points : 1
Points : 1
Bon ben juste après avoir posté mon message j'ai testé une requête préparé... et ça a fonctionné !

Merci beaucoup !

Mais maintenant j'ai un autre problème :

Maintenant, le lien vers la sous catégorie "Maison d'autrefois" s'affiche sans problème, mais le lien en lui même n'est pas bon, en effet, les liens son créés ainsi :

Code :
echo "<a href='client_categories.php?page=0&categories=" . $_GET['categories'] . "&sub_categories=" . $sub_cat . "&enter=yes' >" . $sub_cat . " (" . $rep_nombre->rowCount() . ")<a/> <br />";
et avec Maison d'autrefois j'obtiens :

Code :
http://localhost/client_categories.php?page=0&categories=D%E9coration&sub_categories=Maison%20d
J'ai d'ailleurs un problème similaire avec Chick & Fun :

Code :
http://localhost/client_categories.php?page=0&categories=D%E9coration&sub_categories=Chick%20&%20Fun&enter=yes
le $_GET['sub_categories'] ne trouve que Chick, c'est normal vu qu'il y a & qui sépare les différents paramètres...

Comment faire ?
thedeadman est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité Cette discussion est résolue.
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 18h48.


 
 
 
 
Partenaires

Hébergement Web