Php 将CSV数据导入MySQL

Php 将CSV数据导入MySQL,php,csv,import,Php,Csv,Import,考虑以下来自“NASDAQ.CSV”的CSV数据片段 我正在尝试将符号、扇区和行业导入到一个MySQL表中,其中包含相应的字段: $path = "NASDAQ.csv"; $row = 1; if (($handle = fopen($path, "r")) !== FALSE) { while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) { $row++; $entries[] = $data ; } fcl

考虑以下来自“NASDAQ.CSV”的CSV数据片段

我正在尝试将符号、扇区和行业导入到一个MySQL表中,其中包含相应的字段:

$path = "NASDAQ.csv";
$row = 1;
if (($handle = fopen($path, "r")) !== FALSE) {
  while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) {
    $row++;
    $entries[] = $data ;
  }
  fclose($handle);
}

foreach ($entries as $line) {
  db_query("
     INSERT INTO us_stocks (symbol, name, sector, industry) 
     VALUES ('%s', '%s', '%s', '%s', '%s')",
     $line[0], $line[1], $line[6], $line[7]
  );
}
然而,结果并不是我所期望的。在数据库中,只有符号字段被填充,甚至不正确:

symbol      name  sector  industry
----------------------------------
Symbol,"Na
FLWS,"1-80
FCTY,"1st
FCCY,"1st
我做错了什么

[编辑]

如果我打印r($entries),输出如下

Array (
  [0] => Array(
    [0] => Symbol,"Name","LastSale","MarketCap","ADR TSO","IPOyear","Sector","industry","Summary Quote",;;
  )
  [1] => Array(
    [0] => FLWS,"1-800 FLOWERS.COM, Inc.","2.9","81745200","n/a","1999","Consumer Services","Other Specialty Stores","http://www.nasdaq.com/symbol/flws",;;
  )
  [2] => Array(
    [0] => FCTY,"1st Century Bancshares, Inc","4","36172000","n/a","n/a","Finance","Major Banks","http://www.nasdaq.com/symbol/fcty",;;
  )
)
[编辑二]

我已经按照建议删除了CSV的第一行。我现在有了一个非常快速和肮脏的方式,几乎实现了我想要的。基本上,只要公司名称中有“.Inc”,事情就会搞砸。所以我只是把它“粘”到上面的名字上:$data[1]=$data[1]$资料[2]:

$path = "NASDAQ.csv";
$row = 1;
if (($handle = fopen($path, "r")) !== FALSE) {
  while (($data = fgetcsv($handle, 1000, ";;")) !== FALSE) {
    if ($row < 100) {
      $row++;
      $data = explode(',', $data[0]);
      if (substr($data[2], 0, 1) == ' ') {
        $data[1] = $data[1] . $data[2];
        unset($data[2]);
      }
      $entries[] = $data ;
    }
  }
  fclose($handle);
}
最后一个问题:我不知道如何重新编号。所以3到2,4到3,等等,这样输出看起来像:

[0] => Array
    (
        [0] => FLWS
        [1] => "1-800 FLOWERS.COM Inc."
        [2] => "2.9"
        [3] => "81745200"
        [4] => "n/a"
        [5] => "1999"
        [6] => "Consumer Services"
        [7] => "Other Specialty Stores"
        [8] => "http://www.nasdaq.com/symbol/flws"
        [9] => 
    )

任何帮助都将不胜感激

正如Crontab所说,这可能是引号的问题。尝试:

foreach ($entries as $line) {

  // Escape (see mysql_real_escape_string too) and remove double quotes
  foreach ($line as $k => $v) $line[$k] = mysql_escape_string(trim($v, '"'));

  // Rebuild array
  $line = array_values($line);

  db_query("
    INSERT INTO us_stocks (symbol, name, sector, industry) 
    VALUES ('%s', '%s', '%s', '%s', '%s')",
    $line[0], $line[1], $line[6], $line[7]
 );

}

PS:我不知道您是否已经在
db_query()

中转义了字符串,正如Crontab所说,这可能是引号的问题。尝试:

foreach ($entries as $line) {

  // Escape (see mysql_real_escape_string too) and remove double quotes
  foreach ($line as $k => $v) $line[$k] = mysql_escape_string(trim($v, '"'));

  // Rebuild array
  $line = array_values($line);

  db_query("
    INSERT INTO us_stocks (symbol, name, sector, industry) 
    VALUES ('%s', '%s', '%s', '%s', '%s')",
    $line[0], $line[1], $line[6], $line[7]
 );

}
PS:我不知道您是否已经在
db_query()

中转义了字符串,我想说数据不是“真正的”CSV

“FLWS”、“1-800 FLOWERS.COM有限公司”、“2.9”, 应该是: “FLWS”、“1-800 FLOWERS.COM,INC.”和“2.9”-引号应将各个字段用逗号分隔。通常数字字段不进行包装

根据您加载数据的方式,数据中的逗号可能会混淆数据。(即FLOWERS.COM,INC.)

顺便说一句,如果它真的是CSV,请看:

我想说,数据不是“真正的”CSV

“FLWS”、“1-800 FLOWERS.COM有限公司”、“2.9”, 应该是: “FLWS”、“1-800 FLOWERS.COM,INC.”和“2.9”-引号应将各个字段用逗号分隔。通常数字字段不进行包装

根据您加载数据的方式,数据中的逗号可能会混淆数据。(即FLOWERS.COM,INC.)


顺便说一句,如果它真的是CSV,请看:

我猜它与CSV文件中使用的双引号有关。
fgetcsv()
$enclosure
)的第四个参数可以设置为
“\”“
查看是否是这种情况。我猜这与CSV文件中使用的双引号有关。
fgetcsv()
$enclosure
)的第四个参数可以设置为
“\”
看看情况是否如此。好吧,这肯定不是我见过的最好的csv文件……但它是nasday.com上的可用文件,我找不到任何其他来源来导入所有美国股票的股票代码(我有其他csv,如美国运通、纽约证券交易所,来自同一个网站)。我不能全部删除吗“和‘来自所有字段?’第1行必须有输入错误,因为引号外的符号和名称之间没有分隔符。我只需将所有的”“替换为“(将2 x引号更改为1 x引号)使用加载数据填充跳过第1行,并指定要加载的列..我保证如果使用加载数据填充,插入速度会非常快。可能吧,但现在,我认为在php中对某些东西进行组合对我来说更快…顺便说一句:)如果有时间,请看一下我的最后一个问题-如何重新对键编号。有一个加载数据填充的例子-仅供参考。在另一个问题上,请看数组值和数组键-我确定它们是您想要的。非常快而且脏,我使用$data=array\u merge(array(),$data);来重新索引。问题已解决。谢谢:)嗯,这肯定不是我见过的最好的csv文件…但它是nasday.com上提供的,我找不到任何其他来源来导入所有美国股票的股票代码(我有其他csv,如美国运通、纽约证券交易所,来自同一个网站)。我能不能从所有字段中删除“所有”和“所有字段”?第一行必须有一个打字错误,因为引号外的符号和名称之间没有分隔符。我只需要将所有的“”替换为“(将tr2 x引号更改为1 x引号)使用load data Infle跳过第1行,指定要加载的列。我保证如果使用load data Infle,插入速度会非常快。可能,但现在,我认为在php中对某些东西进行黑客攻击对我来说速度更快…几乎达到了,顺便说一句:)请看一下我的最后一个问题-如何对键重新编号-如果你愿意的话有时间。有一个加载数据填充的例子-仅供参考。在另一个问题上,看看数组值和数组键-我确信它们就是你想要的。非常快而且脏,我使用了$data=array\u merge(array(),$data);重新编制索引。问题已解决。谢谢:)我已经这样做了。但是,它不起作用。您的代码也不起作用。由于双重转义,它现在只读取FLWS、\“1-8等。也许使用regex删除每个$data行中的所有单引号和双引号会更好?
trim($v,“”)
删除字符串开头和结尾的单引号或多引号。因此,恐怕是
fgetcsv()
无法正确解析该CSV。在查询之前,在没有我的代码的情况下,您是否尝试过查看
print\r($line)
?字段是否正确拆分?@Reveller好的,现在您明白了!您只需使用
trim($v,“”)消除双引号即可。
正如我已经向您展示的那样。然后,要消除索引跳转并重新编码数组,只需
array\u values()
。查看我的更新答案:)我已经这样做了。但是,它不起作用。你的代码也不是。由于双转义,它现在只读取FLWS、\“1-8等。也许最好只使用正则表达式从每个$data行中删除所有单引号和双引号?
trim($v,”)
从字符串的开头和结尾删除单引号或多个双引号。因此,恐怕是
fgetcsv()
无法正确解析该CSV。在查询之前,在没有我的代码的情况下,您是否尝试过查看打印($line)的输出?是spli吗
foreach ($entries as $line) {

  // Escape (see mysql_real_escape_string too) and remove double quotes
  foreach ($line as $k => $v) $line[$k] = mysql_escape_string(trim($v, '"'));

  // Rebuild array
  $line = array_values($line);

  db_query("
    INSERT INTO us_stocks (symbol, name, sector, industry) 
    VALUES ('%s', '%s', '%s', '%s', '%s')",
    $line[0], $line[1], $line[6], $line[7]
 );

}