将多个csv文件导入mysql表

时间:2012-05-07 08:22:31

标签: php mysql pdo

更新

我发布此问题之后的第二个问题,由于结果查询的语法突出显示,我看到出现了问题:$pl字符串没有打开,后退结束。现在我把它改成了:

$pk = ',`%1$sUSER`,`%1$sTYPE`,`%1$sCODE`,`%1$sVALUE`,`%1$s';//WRONG
$pk = '`,`%1$sUSER`,`%1$sTYPE`,`%1$sCODE`,`%1$sVALUE`,`%1$s';//OK

但是,这提出了一个新问题:为什么PDO对象为此没有向我发出错误?手动执行查询肯定会返回一个错误,说没有名为fld2_AGE,的字段,最后用逗号。为什么我没有收到任何错误?任何想法?

PS:任何想法都是如何提升SO的语法突出显示来解决我的问题? : - )

我将原始问题作为参考/示例,尽管它不再需要解决


好吧,我一直在使用我写的一段时间来导入从一个巨大的文件中生成几个csv文件,以便快速将数据导入到几个mysql表中。这个脚本在过去(我认为)运行失败,直到我写了第二个脚本,其中我不小心截断了我的表(愚蠢,我知道)。 “没什么大不了的”我想,因为我有了脚本,恢复数据只需几秒钟。不幸的是,我发现现在只导入了一个文件,并且没有显示任何错误。下面我已经粘贴了脚本的整个db部分。当我执行这段代码时,我得到的只是输出files imported successfully,这是最后一行代码......

我知道这是一个失败的大块代码,有很多字符串格式打印,这不会提高可读性,所以我还提供了下面生成的查询字符串。据我所知,它们的格式很好,文件也是如此(我查过)。任何人都可以告诉我还有什么地方可以找错误吗?这将是一个很大的帮助......谢谢!

<?php
$files = array_fill_keys(array('filename1','filename2','filename3','filename4'),'');
//$files === array of handles fputcsv($files['filename1'],array('values','from','other','files'),';');
$tbls = array_combine($files,array('tblname1','tblname2','tblname3','tblname4'));
$path = dirname(__FILE__)'/';
$qf = 'LOAD DATA LOCAL INFILE \'%s%s.csv\' INTO TABLE my_db.tbl_prefix_%s FIELDS TERMINATED BY \';\' OPTIONALLY ENCLOSED BY \'"\' LINES TERMINATED BY \'\n\'';
$pref = array_combine($files,array('fld1_','fld2_','fld3_','fld3_'));
$pkA = ' (`%1$sNAME`,`%1$sAGE';
$pk = '`,`%1$sUSER`,`%1$sTYPE`,`%1$sCODE`,`%1$sVALUE`,`%1$s';
try
{
    $db = new PDO('mysql:host=mysqlhostn','user','pass');
    foreach($files as $f)
    {
        $db->beginTransaction();
        $db->exec(sprintf('TRUNCATE TABLE my_db.tbl_prefix_%s',$tbls[$f]));
        $db->commit();
    }
}
catch(PDOException $e)
{
    if ($db)
    {
        $db->rollBack();
        $db = null;
    }
    die('DB connection/truncate failed: '.$e->getMessage()."\n");
}
try
{
    while($f = array_shift($files))
    {
        $db->beginTransaction();
        $q = sprintf($qf,$path,$f,$tbls[$f]).sprintf($pkA.($f !== 'agent' ? $pk : ''),$pref[$f]);
        switch($f)
        {
            case 'filename3':
                $q .= 'tbl3_specific_field';
            break;
            case 'filename2':
                $q .= sprintf('tbl2_specific_field`,`%1$tbl2_specific_field2',$pref[$f]);
            break;
            case 'filename4':
                $q .= sprintf('tbl4_specific_field`,`%1$tbl4_specific_field2`,`%1$tbl4_specific_field3`,`%1$tbl4_specific_field4',$pref[$f]);
            break;
        }
        $stmt = $db->prepare($q.'`)');
        $stmt->execute();
        $db->commit();
    }
}
catch(PDOException $e)
{
    $db->rollBack();
    $e = 'CSV import Failed: '.$e->getMessage();
    $db=null;
    die($e."\n");
}
$db = null;
exit('files imported successfully'."\n");
?>

生成查询 - 执行输出:

TRUNCATE TABLE my_db.tbl_prefix_tblname1
TRUNCATE TABLE my_db.tbl_prefix_tblname2
TRUNCATE TABLE my_db.tbl_prefix_tblname3
TRUNCATE TABLE my_db.tbl_prefix_tblname4

LOAD DATA LOCAL INFILE '/local/path/to/files/filename1.csv' INTO TABLE my_db.tbl_prefix_tblname1 FIELDS TERMINATED BY ';' OPTIONALLY ENCLOSED BY '"' LINES TERMINATED BY '\n' (`fld1_NAME`,`fld1_AGE`)
LOAD DATA LOCAL INFILE '/local/path/to/files/filename2.csv' INTO TABLE my_db.tbl_prefix_tblname2 FIELDS TERMINATED BY ';' OPTIONALLY ENCLOSED BY '"' LINES TERMINATED BY '\n' (`fld2_NAME`,`fld2_AGE,`fld2_USER`,`fld2_TYPE`,`fld2_CODE`,`fld2_VALUE`,`fld2_tbl2_specific_field`,`fld2_tbl2_specific_field2`)
LOAD DATA LOCAL INFILE '/local/path/to/files/filename3.csv' INTO TABLE my_db.tbl_prefix_tblname3 FIELDS TERMINATED BY ';' OPTIONALLY ENCLOSED BY '"' LINES TERMINATED BY '\n' (`fld3_NAME`,`fld3_AGE,`fld3_USER`,`fld3_TYPE`,`fld3_CODE`,`fld3_VALUE`,`fld3_tbl3_specific_field`)
LOAD DATA LOCAL INFILE '/local/path/to/files/filename4.csv' INTO TABLE my_db.tbl_prefix_tblname4 FIELDS TERMINATED BY ';' OPTIONALLY ENCLOSED BY '"' LINES TERMINATED BY '\n' (`fld4_NAME`,`fld4_AGE,`fld4_USER`,`fld4_TYPE`,`fld4_CODE`,`fld4_VALUE`,`fld4_tbl4_specific_field`,`fld4_tbl4_specific_field2`,`fld4_tbl4_specific_field3`,`fld4_tbl4_specific_field4`)
  

csv导入成功

File1正在导入,因为我需要它,第一个文件的示例:

  

11; 9

虽然file2的实际内容(未导入)如下所示:

  

11; 9; 25; 5; FOOBAR; Z; 333; 321; 123

两个第一个字段都包含相同的数据,两个表都有相同的字段定义,相同的存储引擎(InnoDB),整理(UTF-8)......我不知道导致问题的是什么,所以任何建议将不胜感激。

1 个答案:

答案 0 :(得分:1)

  

为什么PDO对象为此没有向我发出错误?

因为MySQL执行了您的查询而没有任何错误。只是因为你写了错误的查询,这绝不意味着MySQL不接受它的查询错误。

每当您以编程方式生成SQL查询时,请验证(通过调试甚至更好的单元测试),查询是否已根据您的目的进行创建。

如果您希望每次发生错误时都获得异常,请启用:

$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);