【问题标题】:Getting Error 500 or Content Encoding Error doing large MySQL inserts from CSV从 CSV 执行大型 MySQL 插入时出现错误 500 或内容编码错误
【发布时间】:2017-08-22 19:57:44
【问题描述】:

/beginnote 这个问题被标记为“重复”。它与引用的问题不同,因为在我的应用程序中,我不能使用 LOAD IN,因为输入文件永远不会被很好地格式化,所以我 - 必须 - 逐行读取它以测试有效记录。

另外:在我的工作代码中,我已从 mysql_ 更改为 mysqli,并且出现了相同的症状。

另外:我的主机提供商告诉我,我收到的浏览器错误(500 或内容编码错误)不会显示在服务器日志中。

我想重新打开它并了解如何解决问题。 /尾注

我在尝试从 Firefox 和 Chrome 中的 CSV 文件将记录插入 MySQL 时遇到错误。 CSV 文件有 300,000 行。它将是“您尝试查看的页面无法显示,因为它使用了无效或不受支持的压缩形式。”或者只是一个错误 500。

是缓冲区被填满的问题吗?我尝试使用 ob_clean() 和 flush() 但这不起作用。想法?

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  <title>Process uploaded CSV file for Seatac Noise</title>
  <link rel="stylesheet" type="text/css" href="style.css" />
</head>

<?php
error_reporting(E_ALL);
//echo "<pre>" . PHP_EOL;
$database = "jch";
$user     = "jch";
$password = "password";
$connector = 'jch.55.com';
$link = mysql_connect($connector,$user,$password);
mysql_select_db($database) or die( "Unable to select database");
$filter = $_POST["filter"];
$uploaddir = '/uploads';

$path = $uploaddir  . $filter . basename($_FILES['ufile']['name']);

if($ufile != none)
{ 
if (move_uploaded_file($_FILES['ufile']['tmp_name'], $path)) {
  echo "File is valid and was successfully uploaded.\n";

    $row = 0;
    if (($handle = fopen($path, "r")) !== FALSE) {
    while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) {
    $num = count($data);
    $row++;

            if( strlen($data[4]) > 0 )          
            {

             $monitor_id = $data[1];                                                                                             
                 $time = date("Y-m-d H:i:s", strtotime($data[0]));  

             echo('<p>' . $time . ' rows processed: ' . $row . '</p>');

                 $noise_level = $data[2];                                                                                            
                 $flight_id = $data[4];                                                                                          
                 $aircraft_type = $data[3];                                                                                          

                 $query="INSERT INTO jch_noise_detail_copy (
                        monitor_id,                                                                                          
                        time,
                        noise_level,
                        flight_id,
                        aircraft_type) 
                        VALUES(" . 
                            "'" . $monitor_id . "','" .
                            $time . "'," .
                            $noise_level . ",'" .
                            $flight_id . "','" .
                            $aircraft_type . "')";

                        $result = mysql_query($query);
                        if( mysql_errno($link)!= 0 ){
                                echo $query . "\n";
                                echo mysql_errno($link) . ": " . mysql_error($link) . "\n"  ;
                        }
                }

        }  // end while
        mysql_close();


    }

}
else
    echo 'No Rows found matching this date or filter';  
}
mysql_close();
fclose($handle);
?>
</body>
</html>

【问题讨论】:

  • 请停止使用mysql_*函数。它们已经被弃用超过 3 年了,它们将不再在 PHP 7+ 中工作。您的代码对SQL injection 开放。这基本上意味着您网站的任何访问者只需不到一分钟的时间就可以对您的数据库做任何他们想做的事情。这包括摧毁它。考虑使用MySQLiPDO 而不是与Prepared Statements 结合使用。
  • 您使用的是什么版本的 PHP?我注意到您正在使用 mysql_* 命令,该命令已被弃用了很长时间。错误 500 通常意味着您的代码存在语法或其他致命错误。你的错误日志是怎么说的?
  • 1.您可能不应该通过 Web 界面导入大文件。这不是它的设计目的。 2.如果你坚持做,那么至少使用mysql提供的导入数据的工具:load data infile sql命令。
  • 警告:使用 @ 运算符调用方法时不要抑制错误。如果出现问题,您想了解它并需要采取纠正措施,为用户显示有用的消息,记录问题,等等。如果您忽略试图指出严重问题的错误,也会使此类调试问题变得更加复杂。

标签: php mysql csv content-encoding


【解决方案1】:

在此代码中,您插入 300,000 行,其中包含 300,000 次单独的插入。每次 mysql_query() 创建一个从 php 到 mysql 的单独调用。

您可以使用批量插入对其进行优化 - MySQL Reference

最后查询将如下所示:

INSERT INTO jch_noise_detail_copy (
    monitor_id,                                                                                          
    time,
    noise_level,
    flight_id,
    aircraft_type 
) VALUES ($monitor_id_0, time_0 ...), ($monitor_id_1, time_1, ...), ..., ($monitor_id_N, time_N, ...);

【讨论】:

  • 这非常接近仅链接的答案。
猜你喜欢
  • 2012-06-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-10-09
  • 1970-01-01
  • 1970-01-01
  • 2018-03-11
相关资源
最近更新 更多