Injection SQL depuis un CSV...

Répondre


Cette question est un moyen d’empêcher des soumissions automatisées de formulaires par des robots.
Smileys
:D :) :( :o :shock: :? 8-) :lol: :x :P :oops: :cry: :evil: :twisted: :roll: :wink: :!: :?: :idea: :arrow: :| :mrgreen: =D> #-o =P~ :^o :non: :priere: 8-|
Voir plus de smileys
  Revue du sujet
 

  Étendre la vue Revue du sujet : Injection SQL depuis un CSV...

Re: Injection SQL depuis un CSV...

par AB » 09 janv. 2012, 18:03

Heu... des tables temporaires, où ça ?
Fait voir ce que tu as fais et on te dira si tu peux faire facilement quelque chose de plus optimisé.

Re: Injection SQL depuis un CSV...

par FURAX69 » 09 janv. 2012, 10:51

Bon finalement j'ai choisi de charger mon CSV sans une table temp et de traiter la concordance et les updates via une moulinette... Ca fonctionne parfaitement et ça me satisfait pour l'instant, mais je vais creuser toutes vos réponses pour apprendre :wink:

Re: Injection SQL depuis un CSV...

par FURAX69 » 31 déc. 2011, 10:48

Merci à tous pour ces pistes... Je vais creuser tout ça ;)

Terminez bien 2011 et bon réveillon :wink:

Re: Injection SQL depuis un CSV...

par AB » 29 déc. 2011, 18:12

Après je n'ai pas regarder en détails le on duplicate key, la question qui me vient c'est : ça se passe lorsque la clef unique n'est pas la clef primaire ? (j'imagine un numéro de compte alphanumérique et une clef auto incrémenté )?
@+
Je vois pas où est le problème... :-k

Au besoin tu peux créer une clef primaire composée de l'id+numero de compte.

Maintenant je ne dis pas que c'est à utiliser dans tous les cas, mais dans de nombreux cas ça permet de faire la même requête pour l'insertion de nouvelles lignes et leur modification. Plus rapide à écrire et plus rapide à exécuter, un vrai bijoux cette commande :wink:

Re: Injection SQL depuis un CSV...

par moogli » 29 déc. 2011, 12:37

Exactement c'est une couche de plus pour séparer logique métier de l'affichage ;)

Ceci dit si le code est voué à rester sur mysql ce n'est pas problème.
Après je n'ai pas regarder en détails le on duplicate key, la question qui me vient c'est : ça se passe lorsque la clef unique n'est pas la clef primaire ? (j'imagine un numéro de compte alphanumérique et une clef auto incrémenté )?


@+

Re: Injection SQL depuis un CSV...

par Mazarini » 29 déc. 2011, 10:32

Travailler avec des procédures stockées permet de sortir le SQL du PHP et de n'avoir que les procédures stockées à modifier pour porter d'un système à l'autre.

Re: Injection SQL depuis un CSV...

par AB » 29 déc. 2011, 05:01

Je vois pas trop l'intérêt d'une procédure stockée. En même temps comme je n'ai pas encore eu à les utiliser... ceci explique peut-être cela :)
Y a-t-il a un avantage de ce système par rapport à un tout bête :
$req = "INSERT INTO furax69 (numero,budget)  
                   VALUES ('123456','45789.8') 
		   ON DUPLICATE KEY UPDATE 
		   budget = VALUES(budget)
	";


dans cet exemple il suffit que "numero" soit déclaré comme unique et ça devrait aller, non ?

ah oui je viens de trouver l'avantage de ton code : il doit être compatible PostgreSQL alors que le mien ne doit fonctionner qu'avec mysql.
Bah finalement, il reste encore des avantages à travailler avec mysql alors :)
(Et c'est pas demain que je vais changer car mes code sont truffés de INSERT INTO ... ON DUPLICATE KEY UPDATE (car c'est hyper pratique))

Re: Injection SQL depuis un CSV...

par moogli » 28 déc. 2011, 23:49

heu http://dev.mysql.com/doc/refman/5.0/en/ ... icate.html ?

1er lien de cette recherche

sinon pour la méthode avec procédure stockée

La table de test:
CREATE TABLE `furax69` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `numero` int(11) NOT NULL,
  `budget` decimal(8,2) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=latin1
La procédure Stockée
-- --------------------------------------------------------------------------------
-- Routine DDL
-- --------------------------------------------------------------------------------
DELIMITER $$

CREATE DEFINER=`root`@`localhost` PROCEDURE `procFurax69`(
  IN num INT,
	IN bud decimal(10,2),
	out ret boolean)
BEGIN
 declare nb int;
 declare tmp boolean;
 set @tmp := false;
 select count(*) into nb from furax69 where numero = num ;
 if nb = 0 then
	insert into furax69 (numero,budget) value(num,bud);
	set @tmp := true;
 else 
	update furax69 set budget=bud where numero = num;
	set @tmp := true;
 end if;
 select @tmp into ret;
END$$

DELIMITER ;
Le code php avec PDO
<?php
$fichiercsv = file('furax69.csv');
try {
    $pdo = new PDO("mysql:host=localhost;dbname=test;charsey=utf8","root","yyRu2TKEvyYpzFLK");
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    $stmt = $pdo->prepare('call procFurax69(:numero,:budget,@sortie)');
    foreach($fichiercsv as $line){
        $csv = str_getcsv($line, ';');
        /*
        $num = 12;
        $bud = 45550.52;
        */
        $stmt->bindParam(':numero', $csv[0], PDO::PARAM_INT);
        $stmt->bindParam(':budget', $csv[1], PDO::PARAM_INT);
        //$stmt->bindParam(':sortie', $retour, PDO::PARAM_STR,5);
        $stmt->execute();
        $s = $pdo->query('select @sortie')->fetch(PDO::FETCH_OBJ);
        echo 'La procédure à retourné : ', $s->{'@sortie'};
    }
}
catch (PDOException $e){
    echo '<pre style="word-wrap:break-word;">';
    echo $e->getMessage();
    echo '</pre>';
}
?>
Le fichier de test

Code : Tout sélectionner

123456;45789.8 456789;789.5 7832;486.48 159753;486.58 458652;965.12 546;456.25 456.15;48996.52
résultat

Code : Tout sélectionner

mysql> select * from furax69; +----+--------+----------+ | id | numero | budget | +----+--------+----------+ | 1 | 123456 | 45789.80 | | 2 | 456789 | 789.50 | | 3 | 7832 | 486.48 | | 4 | 159753 | 486.58 | | 5 | 458652 | 965.12 | | 6 | 546 | 456.25 | | 7 | 456 | 48996.52 | +----+--------+----------+ 7 rows in set (0.00 sec)
un tuto sur les procédure stockée pour mysql
un tuto sur PDO

Ce code à le mérite d'être a peux prêt standard, donc fonctionnel quelque soit le SGBD ;)

@+

Re: Injection SQL depuis un CSV...

par FURAX69 » 28 déc. 2011, 10:02

Merci de vos réponses, mais étant débutant, je n'ai pas compris grand chose...

Rien de plus parlant qu'un exemple de code, donc si quelqu'un sait où je peux trouver ça ?

Re: Injection SQL depuis un CSV...

par AB » 27 déc. 2011, 21:48

Je suppose que tu sais lire le fichier.

Il faut faire une tentative d'update avec les données lues et regarder combien de lignes modifiées - mysql_affected_rows() - et faire l'insert si pas de lignes modifiée.

Une option est de commencer par l'insert et de faire un update en cas d'erreur duplicate key.
Heu... n''est-ce pas là tout l'intérêt de la syntaxe : INSERT INTO ... ON DUPLICATE KEY UPDATE
Avec ça tu fais l'équivalent de tes deux requêtes en une seule.

Re: Injection SQL depuis un CSV...

par moogli » 27 déc. 2011, 16:00

avec la niveau d'erreur adéquat sinon E_WARNING ? :)

enfin s'pa grave y a deux possibilités a exploiter la ;)

@+

Re: Injection SQL depuis un CSV...

par Mazarini » 27 déc. 2011, 15:21

Pour capturer les erreurs : mysql_errno()

Re: Injection SQL depuis un CSV...

par moogli » 27 déc. 2011, 14:13

Hum tu va être obliger d'indiquer comment capturer les erreurs ;)

Plus sérieusement, pour plus d'info sur SQL => sqlpro sur développez.com.

Une procédure stockée ce n'est pas compliqué à mettre en oeuvre ;)

Pour pdo http://www.php.net/pdo


@+

Re: Injection SQL depuis un CSV...

par Mazarini » 27 déc. 2011, 12:54

Je suppose que tu sais lire le fichier.

Il faut faire une tentative d'update avec les données lues et regarder combien de lignes modifiées - mysql_affected_rows() - et faire l'insert si pas de lignes modifiée.

Une option est de commencer par l'insert et de faire un update en cas d'erreur duplicate key.

Re: Injection SQL depuis un CSV...

par FURAX69 » 27 déc. 2011, 12:18

Salut,
Dans ton cas tu peux regarder du côté du replace de mysql mais Perso je m'orienterais vers une procédure stockée à de. Paramètres. Cette procédure fait un sélect count pour savoir si la ligne existe, si oui iodate si non insert.
Je te conseil aussi l'utilisation de pdo et des requêtes préparée. ;)
@+
Rien compris de tout ça... Mais je vais chercher...