2017-03-08 73 views
1

因此,我非常高兴地使用Load Data infile将数据上载到数据库中的多个表。我的问题是上传的数据包含格式不正确的数据,例如d/m/Y的日期而不是Y-m-d。通过PHP上载到MYSQL并通过Load Data InFile验证数据通过PHP

这并不妨碍数据被插入,它只是将它作为0000-00-00插入。我所希望的是它失败了,所以我可以通知用户在继续之前修复数据。

我目前在做一个检查,以确保上传使用以下的小功能比较它针对样本文件包含正确的列文件:

function check_csv($f_a, $f_b) 
{ 
    $csv_upload = array_map("str_getcsv", file($f_a,FILE_SKIP_EMPTY_LINES))[0]; 
    $csv_sample = array_map("str_getcsv", file($f_b,FILE_SKIP_EMPTY_LINES))[0]; 
    $match = 'true'; 
    foreach ($csv_sample as $key => $value) { 
     if($value != $csv_upload[$key]){ 
      $match = 'false'; 
      break 1; 
     } 
    } 
    return $match; 
} 

...我终于明白,是和array_diff()在这里可能有用的功能,我将在稍后探讨。

回到现在的问题,我是否需要在此函数中执行一些操作来检查每个值,或者是否有Load Data Infile选项可以强制执行我期望的操作。

回答

1

我想说的是,在使用LOAD DATA INFILE的时候,试图在MySQL中进行验证,这实际上是一种无用的练习。首先,您使用LOAD DATA INFILE作为比通过解析器更快的替代方法。如果你想在那里开始放慢速度并进行所有的解析方式,你可能不会使用LOADA DATA INFILE。

我建议你只需在PHP上对CSV进行验证,然后在尝试通过MySQL运行它之前保释(必要)。这实际上会更有效率,因为如果数据甚至不是有效的,你根本不必打扰MySQL。

此外,您用于验证上述CSV文件的代码仅比较CSV第一行的值。这实际上并没有验证任何正在进行的行具有正确的列数。您也不需要array_diff()。只需将CSV中每一行的列数与预期列数进行比较即可。

例如,假设您希望在CSV每行中正好是4列,并且希望列2至有Y-m-d格式化的日期:

$row = 1; 
$expectedColumnNum = 4; // we expect exactly 4 columns 
if (($handle = fopen("uploaded.csv", "r")) !== FALSE) { 
    while (($data = fgetcsv($handle)) !== FALSE) { 
     // Verify every row contains exact number of expected columns 
     if (count($data) != $expectedColumnNum) { 
      echo "CSV does not contain the expected number of columns on row $row!\n"; 
      break; 
     } 
     // Verify the second column is a formatted date of Y-m-d 
     if (!DateTime::createFromFormat('Y-m-d', $data[1])) { 
      echo "CSV does not contain valid formatted date on row $row!\n"; 
      break; 
     } 
     $row++; 
    } 
    fclose($handle); 
} 

如果上面的验证检查出来,那么你”重新使用LOAD DATA INFILE通过MySQL来运行它。

+0

谢谢你,这几乎是我以为我会得到。 关于我的功能,它只是有意识地检查第一行,因为我只是想检查文件是否包含预期的列,并且按照预期的顺序。 由于数据来自相对受控的源,我真的只关心验证第2行(或列头后的第一行数据)的数据,所以我会把你的日期检查片段用于良好的使用。 再次感谢 –

+0

此外,我的脚本是一个通用脚本,可处理具有不同列号和名称的不同数据文件。因此我将其与文件的已知良好示例副本进行比较。 –

+0

没关系。您可以读取所需样本文件的标题,然后将每行的列数与样本文件中的列数进行比较。无论如何,你将不得不检查每一行的日期。你所说的没有改变我提供的答案。 – Sherif