簡體   English   中英

PHP / SQL-將CSV上傳到數據庫-每天不同的工作表/多個表

[英]PHP/SQL - Uploading CSV to database - Different sheets daily/Multiple Tables

昨天我問了一個不清楚的問題,現在我將其稍作擴展。 簡而言之,當前項目需要一個簡單的Web界面,用戶可以在其中上傳CSV文件(此網頁已創建)。 我已經為測試文件修改了PHP,但是我的情況要求有所不同。 每天,用戶將上傳1至5個不同的CSV報告。 這些報告大約有110個字段/列,盡管並非所有字段都將填寫在每個報告中。 我創建了一個包含5個表的數據庫,每個表涵蓋110個表中的不同字段。例如,一個表包含有關水表的信息(25個字段),另一個表包含有關在水表上進行的測試的信息(45個字段) )。 我很難找到一種方法,可以將CSV文件上傳后上傳,並將數據拆分到不同的表中。 我聽說過將整個CSV放入一個表中,並使用INSERT語句從那里拆分,但是我對此有疑問:

  1. 有沒有一種方法可以將包含110個字段的CSV放入一個表中而無需創建字段? 還是我必須在MYSQL工作台中創建110個字段,然后在PHP中為每個字段創建一個變量?

  2. 如果沒有,我是否可以從表轉儲中聲明變量,以便正確的數據進入正確的表中?

我對CSV這樣的上傳不太熟悉,通常只是從具有已知文件名的文件夾中提取一個CSV,所以這就是我的困惑所在。 這是我僅用10列就用作簡單測試的PHP。 這樣做是為了確保CSV上傳成功。

<?php

$server = "localhost";
$user = "root";
$pw = "root";
$db = "uwstest";

$connect = mysqli_connect($server, $user, $pw, $db);

if ($connect->connect_error) {
die("Connection failed: " . $conn->connect_error);
}


if(isset($_POST['submit']))
{
$file = $_FILES['file']['tmp_name'];
$handle = fopen($file, "r");
$c = 0;
while(($filesop = fgetcsv($handle, 1000, ",")) !== 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; 
 }
 }
 }?>

根據CSV大小,您可能要考慮使用MySQL的本機CSV導入功能,因為它的運行速度快10到100倍。

如果確實堅持逐行導入,則可以使用PDO進行類似的操作(或使其適應mysqli)。

如果要匹配列,則將csv存儲為關聯數組,或者解析第一行並將其存儲在$ cols之類的數組中。

在這種情況下,$ results是一個關聯數組,用於存儲一行csv,其中column_name => column_value

$cols=implode(',',array_keys($result));
  $vals=':'.str_replace(",",",:",$cols);
  $inserter = $pdo->prepare("INSERT INTO `mydb`.`mytable`($cols) VALUES($vals);");

   foreach ($result as $k => $v) {
   $result[':' . $k] = utf8_encode($v);
   if(is_null($v))
      $result[':' . $k] = null;
      unset($result[$k]);
    }
    $inserter->execute($result);

希望這可以幫助。 我建議使用PDO只是為了避免在CSV數據中可能遇到的各種怪異現象。

這就是我創建列/值的方式。

$is_first=true;
$cols='';
$vals='';
$cols_array=array();
while (($csv = fgetcsv($handle)) !== false) {
if($is_first)
{
$cols_array=$csv;
$cols=implode(',',$csv);
$is_first=false;
$vals=':'.str_replace(",",",:",$cols);
continue;
}

foreach ($result as $k => $v) {
   $result[':' . $cols_array[$k]] = utf8_encode($v);
   if(is_null($v))
      $result[':' . $cols_array[$k]] = null;
      unset($result[$k]);
    }
    $inserter->execute($result);
}

這是我用於CSV導入的代碼。

        $file='data/data.csv';
        $handle = fopen($file, "r");
        $path=realpath(dirname(__FILE__));
        $full_path=$path."/../../$file";
        $cnt = 0;
        $is_first = true;
        $headers=array();
        $bind=array();
        $csv = fgetcsv($handle, 10000, ",");
        $headers=$csv;
        $alt_query='LOAD DATA LOCAL INFILE \''.$full_path.'\' INTO TABLE mytable 
                FIELDS TERMINATED BY \',\'
                ENCLOSED BY \'\"\'
                LINES TERMINATED BY \'\r\n\'
                IGNORE 1 LINES
                (' . implode(',',$headers).')';

echo exec("mysql -e \"USE mydb;$alt_query;\"",$output,$code);

假設表和CSV之間的關系是任意的,但現在是統一的,則只需建立一次對應數組索引->表列即可。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM