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 :

LOAD DATA INFILE qui fonctionne à moitié [MySQL]


Sujet :

PHP & Base de données

  1. #1
    Futur Membre du Club
    Homme Profil pro
    Inscrit en
    Mai 2011
    Messages
    16
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations forums :
    Inscription : Mai 2011
    Messages : 16
    Points : 6
    Points
    6
    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 : 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
     
    /// 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

  2. #2
    Expert éminent sénior

    Profil pro
    Inscrit en
    Septembre 2010
    Messages
    7 920
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2010
    Messages : 7 920
    Points : 10 726
    Points
    10 726
    Par défaut
    comment est crée le SITE_utf8.txt ?

  3. #3
    Futur Membre du Club
    Homme Profil pro
    Inscrit en
    Mai 2011
    Messages
    16
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations forums :
    Inscription : Mai 2011
    Messages : 16
    Points : 6
    Points
    6
    Par défaut
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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

  4. #4
    Expert éminent sénior

    Profil pro
    Inscrit en
    Septembre 2010
    Messages
    7 920
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2010
    Messages : 7 920
    Points : 10 726
    Points
    10 726
    Par défaut
    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

  5. #5
    Futur Membre du Club
    Homme Profil pro
    Inscrit en
    Mai 2011
    Messages
    16
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations forums :
    Inscription : Mai 2011
    Messages : 16
    Points : 6
    Points
    6
    Par défaut
    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 ?

  6. #6
    Expert éminent sénior

    Homme Profil pro
    Développeur Web
    Inscrit en
    Septembre 2010
    Messages
    5 383
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Puy de Dôme (Auvergne)

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

    Informations forums :
    Inscription : Septembre 2010
    Messages : 5 383
    Points : 10 411
    Points
    10 411
    Par défaut
    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.

  7. #7
    Expert éminent sénior

    Profil pro
    Inscrit en
    Septembre 2010
    Messages
    7 920
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2010
    Messages : 7 920
    Points : 10 726
    Points
    10 726
    Par défaut
    le caractère échappement c'est uniquement quand la chaine contient le séparateur de champs ou de lignes

  8. #8
    Futur Membre du Club
    Homme Profil pro
    Inscrit en
    Mai 2011
    Messages
    16
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations forums :
    Inscription : Mai 2011
    Messages : 16
    Points : 6
    Points
    6
    Par défaut
    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 ?

    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 ?

  9. #9
    Expert éminent sénior

    Profil pro
    Inscrit en
    Septembre 2010
    Messages
    7 920
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2010
    Messages : 7 920
    Points : 10 726
    Points
    10 726
    Par défaut
    montre plutôt une ligne qui ne fonctionne pas,

  10. #10
    Futur Membre du Club
    Homme Profil pro
    Inscrit en
    Mai 2011
    Messages
    16
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations forums :
    Inscription : Mai 2011
    Messages : 16
    Points : 6
    Points
    6
    Par défaut
    Par exemple, avec la ligne :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1263	145	Décoration	Maison d'autrefois	280439	LOT 4 HORLOGES MARGAUX	N10
    j'ai, lors du listage de toute les catégories :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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 ?

  11. #11
    Expert éminent sénior

    Homme Profil pro
    Développeur Web
    Inscrit en
    Septembre 2010
    Messages
    5 383
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Puy de Dôme (Auvergne)

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

    Informations forums :
    Inscription : Septembre 2010
    Messages : 5 383
    Points : 10 411
    Points
    10 411
    Par défaut
    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.

  12. #12
    Futur Membre du Club
    Homme Profil pro
    Inscrit en
    Mai 2011
    Messages
    16
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations forums :
    Inscription : Mai 2011
    Messages : 16
    Points : 6
    Points
    6
    Par défaut
    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 ?

  13. #13
    Expert éminent sénior

    Profil pro
    Inscrit en
    Septembre 2010
    Messages
    7 920
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2010
    Messages : 7 920
    Points : 10 726
    Points
    10 726
    Par défaut
    normalement t'as pas besoin d’échapper les valeurs
    t'as essayé avec un simple INSERT en requete préparée

  14. #14
    Futur Membre du Club
    Homme Profil pro
    Inscrit en
    Mai 2011
    Messages
    16
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations forums :
    Inscription : Mai 2011
    Messages : 16
    Points : 6
    Points
    6
    Par défaut
    Pourquoi j'aurais pas besoin d'échapper les valeurs ?

    J'ai cette requête :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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é.

  15. #15
    Expert éminent sénior

    Profil pro
    Inscrit en
    Septembre 2010
    Messages
    7 920
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2010
    Messages : 7 920
    Points : 10 726
    Points
    10 726
    Par défaut
    montre comment tu faisais avec tes 3000 lignes

  16. #16
    Futur Membre du Club
    Homme Profil pro
    Inscrit en
    Mai 2011
    Messages
    16
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations forums :
    Inscription : Mai 2011
    Messages : 16
    Points : 6
    Points
    6
    Par défaut
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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 !

  17. #17
    Expert éminent sénior

    Profil pro
    Inscrit en
    Septembre 2010
    Messages
    7 920
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2010
    Messages : 7 920
    Points : 10 726
    Points
    10 726
    Par défaut
    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

  18. #18
    Futur Membre du Club
    Homme Profil pro
    Inscrit en
    Mai 2011
    Messages
    16
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations forums :
    Inscription : Mai 2011
    Messages : 16
    Points : 6
    Points
    6
    Par défaut
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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 : 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
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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).

  19. #19
    Expert éminent sénior

    Profil pro
    Inscrit en
    Septembre 2010
    Messages
    7 920
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2010
    Messages : 7 920
    Points : 10 726
    Points
    10 726
    Par défaut
    en requete préparé t'as pas besoin d’échappé les caractères, donc fait une requete préparée.

  20. #20
    Futur Membre du Club
    Homme Profil pro
    Inscrit en
    Mai 2011
    Messages
    16
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations forums :
    Inscription : Mai 2011
    Messages : 16
    Points : 6
    Points
    6
    Par défaut
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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 ?

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. [LOAD DATA INFILE] clé auto incrémentés
    Par ashurai dans le forum Requêtes
    Réponses: 2
    Dernier message: 15/02/2006, 17h17
  2. Réponses: 5
    Dernier message: 18/04/2005, 12h38
  3. probleme avec "LOAD DATA INFILE" et les b
    Par Koo dans le forum Requêtes
    Réponses: 2
    Dernier message: 01/07/2004, 09h37
  4. Problème avec LOAD DATA INFILE
    Par ka0z dans le forum SQL Procédural
    Réponses: 3
    Dernier message: 04/06/2004, 14h59
  5. petit soucis lors d'un LOAD DATA INFILE
    Par Jovial dans le forum SQL Procédural
    Réponses: 9
    Dernier message: 04/06/2004, 11h58

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