【问题标题】:"SQLSTATE[HY000]: General error" when inserting CSV file to database in Symfony2在 Symfony2 中将 CSV 文件插入数据库时​​出现“SQLSTATE [HY000]:一般错误”
【发布时间】:2014-09-29 22:51:06
【问题描述】:

我编写了一个脚本,允许客户端上传 CSV 数据文件,然后将其输入数据库。该脚本首先将 CSV 文件上传到服务器,然后脚本的第二部分读取 CSV 文件,然后将该信息输入到数据库中。

但是,当 CSV 数据插入数据库时​​,我收到以下错误:

SQLSTATE[42000]:语法错误或访问冲突:1064 你有一个 SQL 语法错误;检查与您对应的手册 MariaDB 服务器版本,可在附近使用正确的语法 'UK,Managed,Company UK Glasgow,Glasgow,G1 G1 1AA,3723,Completed,Scheduled,2014-03' 第 1 行

这是 CSV 数据:

account_number,customer_reference,billing_customer,division,customer_site,town,postcode,job_number,job_status,job_type,completion_date,description,waste_type,ewc_code,container,quantity,total_uom,co2_saving,total_resource,total_co2_saving,recovery_rate,disposal_method,waste_hierarchy,customer_order_date,job_notes,customer_ref_po,uploaded,processed,deleted
1,633,Company UK,Managed,Company UK Glasgow,Glasgow,G1 G1 1AA,3723,Completed,Scheduled,2014-03-24,24/05/2014 - General Waste,General Waste to Energy,20 03 01,Wheelie Bin 1100 Litre,4,320,0.84,0,0.03,0,Transfer Station,Incinerator,2014-05-27,,0,2014-08-05,1,0

这是带有上传和 CSV 插入脚本的控制器: $fileUpload = $this->createForm(new FileuploadType());

    $request = $this->getRequest();

    if($request->getMethod() == 'POST') {
        $fileUpload->bind($request);

        $dir = '/var/www/cwwa/web/uploads/csv/';

        if($fileUpload->isValid()) {
            $file2 = $fileUpload['attachment']->getData();
            $file2->move($dir, $file2->getClientOriginalName());

            $fileName = $file2->getClientOriginalName();

            $uploadedFile = basename($dir.''.$file2->getClientOriginalName());

            $recordData = array();
            $table = 'enviro_figures_upload';

            if (($file = fopen($dir.$fileName, "r")) !== FALSE) {

                $row = 0;

                while (($data = fgetcsv($file, 1000, ",")) !== FALSE) {
                    if ($row == 0) {
                        $fieldNames = $data;
                        $row++;
                    } else {
                        $recordData[] = $data;
                        $row++;
                    }
                }

            }

            $fields = implode(',', $fieldNames);

            foreach ($recordData as $record) {
                $values = implode(',',$record);

                $sql = "INSERT INTO $table ($fields) VALUES ($values);";

            }

            $rsm = new ResultSetMapping($dm);
            $insert = $dm->createNativeQuery($sql, $rsm);

            $result = $insert->getResult();

        }
    }

我给数据加了引号,还是出现错误。

编辑
我改变了这一行:

$values = implode(',',$record);

到这里:

$values = '"'.implode(',',$record).'"';

这会将引号添加到要添加的值中,但这会导致值字符串的任一侧出现引号。见下文:

An exception occurred while executing 'INSERT INTO enviro_figures_upload (account_number,customer_reference,billing_customer,division,customer_site,town,postcode,job_number,job_status,job_type,completion_date,description,waste_type,ewc_code,container,quantity,total_uom,co2_saving,total_resource,total_co2_saving,recovery_rate,disposal_method,waste_hierarchy,customer_order_date,job_notes,customer_ref_po,uploaded,processed,deleted) VALUES (1,633,Company UK,Managed,Company UK Glasgow,Glasgow,G1 G1 1AA,3723,Completed,Scheduled,2014-03-24,24/05/2014 - General Waste,General Waste to Energy,20 03 01,Wheelie Bin 1100 Litre,4,320,0.84,0,0.03,0,Transfer Station,Incinerator,2014-05-27,,0,2014-08-05,1,0);':

SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'UK,Managed,Company UK Glasgow,Glasgow,G1 G1 1AA,3723,Completed,Scheduled,2014-03' at line 1

编辑 2
继 VMai 的评论后提出以下建议:

$values = '"' . implode('","',$record) . '"';

这解决了 SQLSTATE 问题。但是,它引发了一个新问题:

SQLSTATE[HY000]:一般错误

我检查了数据库并且查询确实插入了一行数据,无论 CSV 文件中有多少行。刷新页面然后将同一行数据插入到数据库中。

【问题讨论】:

  • 仍然缺少开头和结尾的单引号:$values = "'". implode(',',$record) . "."; 应该这样做。但这不是一个可靠的解决方案。如果其中一个字段包含单引号或类似的东西怎么办?
  • 正如您所说,某些实际数据确实包含单引号。我想我可以反转它,做'"'。我会试试这个。
  • 假设 Doctrine 为 ORM,我建议使用准备好的语句,看看docs.doctrine-project.org/projects/doctrine-dbal/en/latest/…。有些值肯定也会有双引号......
  • 我已根据您的第一条评论更新了我的答案。
  • 我观察得不够多 :-( 你必须与你的引号保持一致并引用 csv 文件的每个字段:它应该是 $values = '"' . implode('","',$record) . '"'; 以使所有值正确引用双引号。希望您的值中没有像 19" rack 这样的值...

标签: mysql sql symfony csv mariadb


【解决方案1】:

Symfony 2.3

我建议使用 object (flush) ,但是如果你使用没有实体的 sql,试试这个

foreach ($recordData as $record) {

    $values = '"'. implode('","',$record) . '"';
    $sql = "INSERT INTO $table ($fields) VALUES ($values);";
    $em = $this->getDoctrine()->getManager()->getConnection()->prepare($sql);
    $em->execute();
}

【讨论】:

  • edit 提供更多信息。纯代码和“试试这个”的答案是discouraged,因为它们不包含可搜索的内容,也没有解释为什么有人应该“试试这个”。我们在这里努力成为知识的资源。
【解决方案2】:

您必须为每条记录执行 INSERT:

应该是这样的

// I assume we need only one of this
$rsm = new ResultSetMapping($dm);

foreach ($recordData as $record) {
    $values = '"'. implode('","',$record) . '"';
    $sql = "INSERT INTO $table ($fields) VALUES ($values);";

    $insert = $dm->createNativeQuery($sql, $rsm);
    $result = $insert->getResult();
}

相反。

备注

我建议使用准备好的语句。在循环之前准备一次,并在循环内为每条记录绑定输入值来执行它。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-10-24
    • 2017-06-25
    • 2016-06-27
    • 1970-01-01
    • 2012-10-25
    • 2014-12-31
    • 1970-01-01
    相关资源
    最近更新 更多