Page 1 sur 1

Problème d'insertion très complexe (besoin d'un pro)

Posté : 31 mai 2005, 10:54
par BFH
Bonjour,
voici une partie de mon code pour une insertion complexe
if(file_exists($FI))//si le fichier exist
{
$fichier=file("$FI");//parcours le fichier csv ligne par ligne et stocke chaque ligne dans un tableau
		
$query="SELECT NextID FROM nextid";
$result=mysql_query($query);
$row=mysql_fetch_assoc($result);

$ID=$row["NextID"];
$NextID=$ID+1;
$F1=addslashes($FI);
				
$insert="LOAD DATA INFILE '".$FI."' INSERT INTO TABLE 'item' FIELDS TERMINATED BY ';'LINES TERMINATED BY '\\n\\r' IGNORE 9 LINES  (INum,IPage,IDevice,IGroup,IValue,IID) ";

mysql_query($insert)or die(mysql_error());
}
Ma table item compte comme champs (INum,IPage,IDevice,IGroup,IValue,IID, ReportID)

Je voudrais remplir le champs ReportID avec $ID pour chaque ligne qui sera en provenance de $F1 qui sera insérée

Est ce que quelqu'un connait la bonne formulation à cette requête ??

Posté : 31 mai 2005, 21:06
par Cyrano
Juste au cas où : où est situé le fichier ? Je viens de trouver ceci:
Si le mot clef LOCAL n'est pas spécifié, le fichier doit se trouver sur le serveur
Source ICI

Posté : 01 juin 2005, 08:47
par BFH
Désolé ce n'est pas ça!

Le Mystère de BFH

Posté : 01 juin 2005, 09:04
par sadeq
tu postes deux fois ce problème mais tu n'explique jamais précisement ce que tu veux faire.
D'ailleurs je vois encore quelque lignes de code dans ce que tu présente qui ne servent strictement à rien puisque tu utilise LOAD DATA : je pense à :
$fichier=file("$FI");//parcours le fichier csv ligne par ligne et stocke chaque ligne dans un tableau 

Cette instruction ne fait pas ce que tu commentes ni le programme d'ailleurs. En fait c'est un début non achevé d'une solution concurente de celle de LOAD DATA.

Il faut savoir que la requête LOAD DATA travail en silence c'est une commande batch qui traite les lignes d'un fichier par lot. en d'autre mot ce n'est pas ton programme qui parcours le fichier ligne par ligne => tu n'as aucune prise en main sur le déroulement du traitement de LOAD DATA puisque c'est MYSQL qui l'exécute.

Mais tu peux manipuler la table item après l'avoir rempli par LOAD DATA. pour effectuer une mise à jour des données qui y se trouvent.

Maintenant ton explication est manquante, le code que tu présente n'est pas commenté (on ne sait pas par exemple à quoi sert la petite trouvaille de NextID ou Est-ce le même $ID qui doit affecter toutes les lignes ???)

Je ne peux dire plus.

----------------------------------------------
PS: T'as pas besoin d'un pro pour ça, t'as besoin de comprendre pour agir

Posté : 01 juin 2005, 09:42
par BFH
Je ne crois pas vraiment que je possède des lignes de code qui ne servent à rien c'est juste que je n'ai pas affiché tout le code qui sert à l'insertion. Tiens le voila:
if(file_exists($FI))//si le fichier exist
{
$fichier=file("$FI");//parcours le fichier csv ligne par ligne et stocke chaque ligne dans un tableau
		
$heure = explode(',',$fichier[9]);//$heure divise la ligne n°9 en colone, chaque colone étant marqué par une virgule
$date = explode(',',$fichier[8]);
$user = explode(',',$fichier[6]);
		
$H=$heure[5];//$H= la 5ème colone crée par $heure
$D=$date[5];
		
$RHost=basename($FI, ".csv");//recupère juste le nom du fichier (ce qu'il y a après le dernier slash privé de .csv)
$RDateTime=$D.$H;
$RUser=$user[5];
		
$query="SELECT NextID FROM nextid";//permet de recuperer le prochain identifiant du fichier qui sera inséré dans la base
$result=mysql_query($query);
$row=mysql_fetch_assoc($result);
$ID=$row["NextID"];	//permet de recuperer la valeur de NextID
NextID=$ID+1;//$NextID egale la valeur précédente de NextID augmenté de 1
$F1=addslashes($FI);	//mets des slashs devant les les caractères spéciaux qui pourraient être contenus dans le chemin du fichier
		
$insert="LOAD DATA INFILE '".$F1."' INSERT INTO TABLE item FIELDS TERMINATED BY ','LINES TERMINATED BY '\\n\\r' IGNORE 9 LINES (INum,IPage,IDevice,IGroup,IValue,IID)";

$insert2="INSERT INTO TABLE report (ID_R,RHost) VALUES ('$ID','$RHost') ";			
$insert3="INSERT INTO TABLE nextid (NextID) VALUES ('$NextID') ";
		
mysql_query($insert)or die(mysql_error());
		
mysql_query($insert2)or die(mysql_error());
		
mysql_query($insert3)or die(mysql_error());
}
Maintenant ce que je veux c'est :
_ Comprendre pourquoi la ligne suivante ne fonctionne pas :
$insert="LOAD DATA INFILE '".$F1."' INSERT INTO TABLE item FIELDS TERMINATED BY ','LINES TERMINATED BY '\\n\\r' IGNORE 9 LINES (INum,IPage,IDevice,IGroup,IValue,IID)";
_ Qu'on me dise comment faire pour :
Je voudrais remplir le champs ReportID avec $ID pour chaque ligne qui sera en provenance de $F1 qui sera insérée

Ma table item compte comme champs (INum,IPage,IDevice,IGroup,IValue,IID, ReportID)
Parce que la ma variable $insert ne le fait pas

$fichier=file("$FI");//parcours le fichier csv ligne par ligne et stocke chaque ligne dans un tableau  
Cette instruction ne fait pas ce que tu commentes
Si t'es pas d'accord avec mon commentaire tu peut t'adresser à monsieur François-Xavier BOIS auteur du livre PHP, un accompagnement pour maitriser les bases de la programmation pour lui adresser tes repproches!

Posté : 01 juin 2005, 10:58
par zeus
ta variable $F1 contient un chemin absolu ou relatif ?

Posté : 01 juin 2005, 11:13
par BFH
Elle contient un chemin absolu.
Mais sinon j'ai essayé un autre code:
if(isset($_GET["FI"]))
{
$FI=$_GET["FI"];
//$FI retourne le chemin absolu du fichier csv que l'on veut inserer dans la base
}
if(file_exists($FI))//si le fichier exist
{
$fichier=file("$FI");//parcours le fichier csv ligne par ligne et stocke chaque ligne dans un tableau
$compte=count($fichier);
		
$heure = explode(',',$fichier[9]);//$heure divise la ligne n°9 en colone, chaque colone étant marqué par une virgule
$date = explode(',',$fichier[8]);
$user = explode(',',$fichier[6]);
		
$H=$heure[5];//$H= la 5ème colone crée par $heure
$D=$date[5];
		
$RHost=basename($FI, ".csv");//recupère juste le nom du fichier (ce qu'il y a après le dernier slash privé de .csv)
$RDateTime=$D.$H;
$RUser=$user[5];
		
$query="SELECT NextID FROM nextid";
$result=mysql_query($query);
$row=mysql_fetch_assoc($result);
$ID=$row["NextID"];	//permet de recuperer la valeur de NextID
$NextID=$ID+1;//$NextID egale la valeur précédente de NextID augmenté de 1
$F1=addslashes($FI);	//mets des slashs devant les les caractères spéciaux qui pourraient être contenus dans le chemin du fichier
		
for($i=10; $i<=count($fichier); $i++)
{
$ligne=explode(',',$fichier[$i]);   //bug
$IPage=$ligne["0"];                   //bug
$IPage=addslashes($IPage);
$IDevice=$ligne["1"];                //bug
$IDevice=addslashes($IDevice);
$IGroup=$ligne["2"];                 //bug
$IGroup=addslashes($IGroup);
$IField=$ligne["4"];                   //bug
$IField=addslashes($IField);
$IValue=$ligne["5"];                 //bug
$IValue=addslashes($IValue);
$IID=$ligne["3"];                      //bug
$IID=addslashes($IID);
$insert="INSERT INTO item (IPage,IDevice,IGroup,IField,IValue,IID,ReportID) VALUES ('".$IPage."','".$IDevice."','".$IGroup."','".$IField."','".$IValue."','".$IID."','".$ID."')";
mysql_query($insert)or die(mysql_error());
}
		
$insert2="INSERT INTO TABLE report (ID_R,RHost) VALUES ('".$ID."','".$RHost."') ";			
$insert3="INSERT INTO TABLE nextid (NextID) VALUES ('".$NextID."') ";
			
mysql_query($insert2)or die(mysql_error());
mysql_query($insert3)or die(mysql_error());
}
ça semble fair l'insertion a peut pres correctement mais ça me retourne :
Notice: Undefined offset: 436 in c:\program files\easyphp1-8\www\php\insertion.php on line 39

Notice: Undefined index: 1 in c:\program files\easyphp1-8\www\php\insertion.php on line 42

Notice: Undefined index: 2 in c:\program files\easyphp1-8\www\php\insertion.php on line 44

Notice: Undefined index: 4 in c:\program files\easyphp1-8\www\php\insertion.php on line 46

Notice: Undefined index: 5 in c:\program files\easyphp1-8\www\php\insertion.php on line 48

Notice: Undefined index: 3 in c:\program files\easyphp1-8\www\php\insertion.php on line 50
pourquoi??

Posté : 01 juin 2005, 12:41
par Cyrano
Tu as mis des index numériques entre guillemet dans tes tableaux:
<?php
if(isset($_GET["FI"]))
{
    $FI=$_GET["FI"];
    //$FI retourne le chemin absolu du fichier csv que l'on veut inserer dans la base
}
if(file_exists($FI))//si le fichier exist
{
    $fichier=file("$FI");//parcours le fichier csv ligne par ligne et stocke chaque ligne dans un tableau
    $compte=count($fichier);

    $heure = explode(',',$fichier[9]);//$heure divise la ligne n°9 en colone, chaque colone étant marqué par une virgule
    $date = explode(',',$fichier[8]);
    $user = explode(',',$fichier[6]);

    $H=$heure[5];//$H= la 5ème colone crée par $heure
    $D=$date[5];

    $RHost=basename($FI, ".csv");//recupère juste le nom du fichier (ce qu'il y a après le dernier slash privé de .csv)
    $RDateTime=$D.$H;
    $RUser=$user[5];

    $query="SELECT NextID FROM nextid";
    $result=mysql_query($query);
    $row=mysql_fetch_assoc($result);
    $ID=$row["NextID"];    //permet de recuperer la valeur de NextID
    $NextID=$ID+1;//$NextID egale la valeur précédente de NextID augmenté de 1
    $F1=addslashes($FI);    //mets des slashs devant les les caractères spéciaux qui pourraient être contenus dans le chemin du fichier

    for($i=10; $i<=count($fichier); $i++)
    {
        $ligne=explode(',',$fichier[$i]);   //bug
        $IPage=$ligne[0];                   //bug
        $IPage=addslashes($IPage);
        $IDevice=$ligne[1];                //bug
        $IDevice=addslashes($IDevice);
        $IGroup=$ligne[2];                 //bug
        $IGroup=addslashes($IGroup);
        $IField=$ligne[4];                   //bug
        $IField=addslashes($IField);
        $IValue=$ligne[5];                 //bug
        $IValue=addslashes($IValue);
        $IID=$ligne[3];                      //bug
        $IID=addslashes($IID);
        $insert="INSERT INTO item (IPage,IDevice,IGroup,IField,IValue,IID,ReportID) VALUES ('".$IPage."','".$IDevice."','".$IGroup."','".$IField."','".$IValue."','".$IID."','".$ID."')";
        mysql_query($insert)or die(mysql_error());
    }

    $insert2="INSERT INTO TABLE report (ID_R,RHost) VALUES ('".$ID."','".$RHost."') ";
    $insert3="INSERT INTO TABLE nextid (NextID) VALUES ('".$NextID."') ";

    mysql_query($insert2)or die(mysql_error());
    mysql_query($insert3)or die(mysql_error());
}
?>
Essaye avec ça, ça devrait supprimer au moins 5 erreurs.

Posté : 01 juin 2005, 13:01
par sadeq
désolé pour la provocation, le post qui a suivi est bien meilleur et plus riche.

Il y a une erreur de frappe dans la requête $insert : il faut ajouter un espace entre ',' et LINES TERMINATED.

Pour l'ID du report, tu peux mettre à jour la table item en plaçant $ID dans le champs ReportID par une requête UPDATE.

Comme :
.....
$insert="LOAD DATA INFILE '".$F1."' INSERT INTO TABLE item FIELDS TERMINATED BY ',' LINES TERMINATED BY '\\n\\r' IGNORE 9 LINES (INum,IPage,IDevice,IGroup,IValue,IID)"; 

$insert2="INSERT INTO TABLE report (ID_R,RHost) VALUES ('$ID','$RHost') ";             
$insert3="INSERT INTO TABLE nextid (NextID) VALUES ('$NextID') "; 

$insert4="UPDATE item SET ReportID='$ID' "; 

mysql_query($insert)or die(mysql_error()); 
         
mysql_query($insert2)or die(mysql_error()); 
         
mysql_query($insert3)or die(mysql_error()); 

mysql_query($insert4)or die(mysql_error()); 


Posté : 01 juin 2005, 20:55
par BFH
Cyrano, désolé mais cela ne fonctionne pas!

Posté : 01 juin 2005, 21:10
par Cyrano
J'ai peut-être trouvé BFH, en faisant une toute petite poptimisation sur une ligne, j'ai réalisé qu'il y avait de toutes façon une erreur:
J'ai changé le contenu des conditions de la boucle for:
for($i = 10; $i< $compte; $i++)
Au lieu de faire compter le nombre à chaque tour, autant utiliser une variable qui contient déjà ce nombre. MAIS...

Au lieu de "<=", j'ai viré le "=" parce que ça fait faire un tour de trop. Exemple, tu as un tableau qui contient 25 lignes. Le tableau commençant à zéro, on doit s'arrêter sur la dernière ligne, la vingtcinquième qui est identifiée par l'index... 24

Donc en faisant un tour de trop, tu as des index indéfinis au dernier tour... logique.

Posté : 02 juin 2005, 11:14
par BFH
Merci Gourou, t'es trop fort!

Posté : 02 juin 2005, 11:20
par Cyrano
[Résolu] :?: