0

I'm trying to connect the dots for a few processes. I have a project that requires a CSV to be uploaded via form on webpage, which exists already, on a daily basis. Every time the CSV is loaded in the 110 columns need to be split into about 5 different MySQL tables. The CSV will always be in the same order, but I need to know exactly which variables/columns from the CSV to put into the specific tables and fields. Once this is done, I'll need to display the data on other pages, by query only (only some things will be displayed depending on the page). I have the following code to test putting the CSV into an array:

if(isset($_POST['submit']))
{
$array = $fields = array(); $i=0;
$file = $_FILES['file']['tmp_name'];
$handle = fopen($file, "r");

if($handle){
     while (($row = fgetcsv($handle, 4096)) !== false) {
    if (empty($fields)) {
        $fields = $row;
        continue;
    }
    foreach ($row as $k=>$value) {
        $array[$i][$fields[$k]] = $value;
    }
    $i++;

}

echo "Success!";
var_dump($array);
if (!feof($handle)) {
    echo "Error: unexpected fgets() fail\n";
}
fclose($handle);
}}?>

This seems to work fine with the Var_dump. Then, separately, I've used the following code on a small CSV with only ten fields:

while(($filesop = fgetcsv($handle, 4096, ",")) !== false)
{

 $one = $filesop[0];
 $two = $filesop[1];
 $three = $filesop[2];
 $four = $filesop[3];
 $five = $filesop[4];
 $six = $filesop[5];
 $seven = $filesop[6];
 $eight = $filesop[7];
 $nine = $filesop[8];
 $ten = $filesop[9];

 $sql = "INSERT INTO staging (One, Two, Three, Four, Five, Six, Seven, Eight, Nine, Ten) VALUES ('$one','$two', '$three','$four','$five','$six','$seven','$eight','$nine','$ten')";

 }

 if ($connect->query($sql) === TRUE) {
 echo "You database has imported successfully";
 } else {
 echo "Error: " . $sql . "<br>" . $conn->error; 
 }

I'm still confused on how I can map the 110 fields of these daily uploaded CSV to their correct tables (10 fields into one table, 25 into another, 30 into another, etc. ) so that I can use the variables to display certain fields on other pages.

UPDATE:

New code for arrays:

$table_cols[5] ="workOrderNum,lowSideMIUNum,highSideMIUNum,accountNum,custName,address,locID,utility,serialNumber,serviceName";



$tablenames = array("staging","clients","meters","tests","costs","workorders");

for($tableno = 0;$tableno < sizeof($tablenames);$tableno++){
$q = "";
$q .= "INSERT INTO ".$tablenames[$tableno]." (".$table_cols[$tableno].") VALUES (";
$cols = explode("," ,$table_cols);
$data = array();
foreach($col as $key => $fldname) {
    $data[] = "'".$coldata[$fldname]."'";
}

$q .= implode(",",$data).");";

}
echo'File submitted';

1 Answer 1

1

See Update Below This part of the answer left for context

You could create an array with indexes of the columns to be saved in each table. Then run one insert per table, getting the column values based on the index in your array for that table.

$tbl1_idxs = array(1,4,10,20,15,22);
$tbl2_idxs = array(2,9,1,7,32,44);
$tbl3_idxs = array(27,15,65,110,12);

$q1 = "";
$q1 .= "INSERT INTO `Table1` (`fld1`,`fld2`,`fld3`,`fld4`,`fld5`,`fld6`) ";
$q1 .= "VALUES ('";
$q1 .= $filesop[tbl1_idxs[0]]."','";
$q1 .= $filesop[tbl1_idxs[1]]."','";
$q1 .= $filesop[tbl1_idxs[2]]."','";
$q1 .= $filesop[tbl1_idxs[3]]."','";
$q1 .= $filesop[tbl1_idxs[4]]."','";
$q1 .= $filesop[tbl1_idxs[5]]."');";

//  Execute query #1....

$q2 = "";
$q2 .= "INSERT INTO `Table2` (`fld1`,`fld2`,`fld3`,`fld4`,`fld5`,`fld6`) ";
$q2 .= "VALUES ('";
$q2 .= $filesop[tbl2_idxs[0]]."','";
$q2 .= $filesop[tbl2_idxs[1]]."','";
$q2 .= $filesop[tbl2_idxs[2]]."','";
$q2 .= $filesop[tbl2_idxs[3]]."','";
$q2 .= $filesop[tbl2_idxs[4]]."','";
$q2 .= $filesop[tbl2_idxs[5]]."');";

//  Execute query #2....

$q3 = "";
$q3 .= "INSERT INTO `Table3` (`fld1`,`fld2`,`fld3`,`fld4`,`fld5`,`fld6`) ";
$q3 .= "VALUES ('";
$q3 .= $filesop[tbl3_idxs[0]]."','";
$q3 .= $filesop[tbl3_idxs[1]]."','";
$q3 .= $filesop[tbl3_idxs[2]]."','";
$q3 .= $filesop[tbl3_idxs[3]]."','";
$q3 .= $filesop[tbl3_idxs[4]]."','";
$q3 .= $filesop[tbl3_idxs[5]]."');";

//  Execute query #3....

UPDATED ANSWER

With that many columns, I would map by column name instead. There are several ways this could be made manageable.

In any case, instead of hard variable names for each column of the CSV, I would put them in an associative array, with the keys matching the column names of the tables. You could then have a comma separated list of columns for each table.

You would still have the 203 lines of code to map the CSV fields to names, but maintaining which column goes into which table would at least be readable. And changing the existing code that assigned each CSV column to a variable should be a simple regex search and replace.

$coldata = array();
$coldata['name'] = $filesop[0];
$coldata['addr1'] = $filesop[1];
$coldata['addr2'] = $filesop[2];
$coldata['city'] = $filesop[3];
$coldata['state'] = $filesop[4];
$coldata['zip'] = $filesop[5];
$coldata['country'] = $filesop[6];
$coldata['gender'] = $filesop[7];
$coldata['age'] = $filesop[8];
$coldata['birthdate'] = $filesop[9];

$table_cols = array();

$table_cols[0] = "name,gender,age";
$table_cols[1] = "name,addr1,addr2,city,state,zip";
$table_cols[2] = "name,age,birthdate";

$tablenames = array("staging","info","other");

for($tableno = 0;$tableno < sizeof($tablenames);$tableno++) {
    $q = "";
    $q .= "INSERT INTO ".$tablenames[$tableno]." (".$table_cols[$tableno].") VALUES (";
    $cols = explode(",",$table_cols[$tableno]);
    $data = array();
    foreach($col as $key => $fldname) {
        $data[] = "'".$coldata[$fldname]."'";
    }
    $q .= implode(",",$data).");";

    //    Execute query in $q

}
Sign up to request clarification or add additional context in comments.

19 Comments

Ah, I haven't seen that method yet. So question: We created a php file for reference, in case we needed a variable for every single column. Basically it has 203 lines where I've created a variable ($accountNum, $client, $etc.) for every column of the CSV. This is obviously a lengthy and agonizing way to do it, but it gives us full control of every variable. You're saying I would assocaite every column of the CSV (203) with an array index and then spend my time mapping the index numbers to the correct position in the tables I already have created?
I was just looking over this again and had a few quick questions: First, the coldata array would be about 203 lines long right? Just one long array for every single column? And then, each table_cols array index would be for the 7 tables, so there would be 7 lines there ([0]-[6]) holding all respective names?
@H.Norman: Regarding the table_cols array, that's right. With the updated example, you're still mapping one variable for each column, but since it's in an array it gives you the added advantage of being able to loop through or index to a particular column value. If your CSV has column names in the first line, you can make that part automatic.
I posted on your other thread for this issue. Basically, your column name list should only have the columns used for that table. Do not put placeholders for (ie. null) for columns not saved to that table.
If the column isn't to be written to, leave it out of the list of columns. Even if the table has additional columns not in the CSV, or columns in the CSV not in the table. List only those columns for the particular table that need to be saved.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.