PHP/SQL - 将 CSV 上传到数据库 - 不同的工作表 daily/Multiple 表

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

我昨天问了一个不清楚的问题,现在我稍微扩展了一下。简而言之,这个当前项目需要一个简单的 Web 界面,用户可以在其中上传一个 csv 文件(这个网页已经创建)。我已经为测试文件修改了我的 PHP,但我的情况需要一些不同的东西。每天,用户会上传 1 到 5 个不同的 CSV 报告。这些报告大约有 110 fields/columns,但并不是每份报告都会填写所有字段。我创建了一个包含 5 table 的数据库,每个 table 涵盖 110 个不同的字段。例如,一个 table 包含水表(25 个字段)的信息,另一个table 包含在仪表上完成的测试的信息(45 个字段)。我很难找到一种方法来获取 CSV,一旦上传,并将数据分成不同的 tables。我听说过将整个 CSV 放入一个 table 并使用 INSERT 语句从那里拆分,但我对此有疑问:

  1. 有没有一种方法可以在不创建字段的情况下将具有 110 个字段的 CSV 合并为一个 table?或者我必须在 MYSQL workbench 中创建 110 个字段,然后在 PHP?

  2. 中为每个字段创建一个变量
  3. 如果没有,我能否从 table 转储中声明变量,以便正确的数据进入正确的 table?

就像这样上传而言,我对 CSV 不太熟悉,通常只是从文件名已知的文件夹中提取一个 csv,所以这就是我的困惑所在。这是我用作简单测试的 PHP,只有 10 列。这样做是为了确保 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; 
 }
 }
 }?>

假设 tables 和 CSV 之间的关系是任意但统一的,现在您只需要建立对应数组索引 -> table 列一次。

根据 CSV 大小,您可能需要考虑使用 MySQL 的原生 CSV 导入功能,因为它的运行速度快 10 倍到 100 倍。

如果你坚持逐行导入,那么你可以用PDO做这样的事情(或者适应mysqli)。

如果你想匹配列,那么要么将你的 csv 存储为关联数组,要么解析第一行并将其存储在 $cols 之类的数组中。

在这种情况下,$results 是一个关联数组,它存储了一行 column_name=>column_value

的 csv
$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 数据中可能遇到的各种怪异现象。

这就是我创建 columns/vals 的方式。

$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);