PHP LOAD DATA INFILE仅插入某些文件的第一行

时间:2014-11-25 16:12:28

标签: mysql excel csv xampp

我有一个.dat文件,我从另一个有多行逗号分隔数据的应用程序中提取。我用Excel打开文件,并将其保存为.csv。我可以使用LOAD DATA INFILE将该文件无问题地上传到我的数据库。

但是这里变得奇怪。如果我拿原始文件并尝试复制,例如,20行并创建一个新的.csv文件,当我将它上传到同一个数据库,相同的表模式时,它只会加载第一行。当我保存为新的.csv时,Excel是否对我的格式做了些什么?对我来说看起来一样......与其他文本编辑打开时,我看不出有什么区别。

这是我用于为要导入的数据创建新表的SQL(我首先检查表是否已存在):

// Create table - Table name matches name of file without extension
$sql = "CREATE TABLE " . $file_name . " (
    history_id INT,
    stream_id INT,
    record_time DATETIME,
    ALEQ FLOAT,
    APEAK FLOAT,
    AFASTSPL FLOAT,
    dose FLOAT,
    color INT
)";

这是我加载.csv的SQL:

// Insert data from uploaded .csv file into table
$sql = "LOAD DATA LOCAL INFILE '" . $target_file . "' 
        INTO TABLE " . $file_name . "
        FIELDS OPTIONALLY ENCLOSED BY '''' TERMINATED BY ','
        LINES TERMINATED BY '\n'";

以下是执行工作的文件的.csv:

1,1,'2014-08-28 07:00:31',35.2,56.0,35.1,0.0000000,0
2,1,'2014-08-28 07:00:31',35.1,56.0,35.4,0.0000000,0
3,1,'2014-08-28 07:00:31',35.1,56.0,35.2,0.0000000,0
4,1,'2014-08-28 07:00:31',35.3,56.0,35.0,0.0000000,0
5,1,'2014-08-28 07:00:31',35.2,56.0,35.3,0.0000000,0
6,1,'2014-08-28 07:00:31',35.2,56.0,35.2,0.0000000,0

以下是无效的文件的.csv:

60135,1,'2014-08-28 15:19:19',52,68.3,52.6,0.43186,0
60136,1,'2014-08-28 15:19:20',56.9,71.6,51.3,0.43186,0
60137,1,'2014-08-28 15:19:20',56.5,68.8,58.3,0.43186,0
60138,1,'2014-08-28 15:19:21',57,70.1,56.4,0.43186,0
60139,1,'2014-08-28 15:19:21',56.5,69.2,56.2,0.43186,0
60140,1,'2014-08-28 15:19:22',58.7,71.4,56.7,0.43186,0

1 个答案:

答案 0 :(得分:1)

如果只加载第一行,则表示没有正确检测到行尾。我建议使用十六进制编辑器来检查源文件中的行结尾。

也许你保存为" CSV(Macintosh)"它使用\ r作为行结尾。如果是这种情况,您应该可以使用

LINES TERMINATED BY '\r'";

如果你不知道行结尾,那么这是一个更通用的解决方案...

MySQL没有自动行结束检测,这就是为什么你必须告诉它如何解析数据。您可以使用此短函数进行一些基本的频率分析。

function detectLineEndings($file)
{
    $data = file_get_contents($file);
    $le_linux = substr_count($data, "\n");
    $le_windows = substr_count($data, "\r\n");
    $le_mac = substr_count($data, "\r");

    if ($le_linux > $le_windows && $le_linux > $le_mac) {
        return '\n';
    }
    if ($le_mac > $le_linux && $le_mac > $le_windows) {
        return '\r';
    }
    return '\r\n';
}

$endings = detectLineEndings($target_file);

$sql = "LOAD DATA LOCAL INFILE '" . $target_file . "' 
        INTO TABLE " . $file_name . "
        FIELDS OPTIONALLY ENCLOSED BY '''' TERMINATED BY ','
        LINES TERMINATED BY '" . $endings ."'";