Symfony2 + DBAL。如何使用bindValue进行多次插入?

时间:2016-03-17 13:52:18

标签: symfony dbal

我正在使用DBAL,我想执行多个插入查询。但我遇到了问题:bindValue()方法无法循环工作。这是我的代码:

    $insertQuery = "INSERT INTO `phonebook`(`number`, `company`, `user`) VALUES %s 
           ON DUPLICATE KEY UPDATE company=VALUES(company), user=VALUES(user)";

    for ($i = 0; $i < count($data); $i++) {
        $inserted[] = "(':number', ':company', ':user')";
    }

    $insertQuery = sprintf($insertQuery, implode(",", $inserted));
    $result = $db->getConnection()->prepare($insertQuery);

    for ($i = 0; $i < count($data); $i++) {
        $result->bindValue($data[$i]["number"]);
        $result->bindValue($data[$i]["company"]);
        $result->bindValue($data[$i]["user"]);
    }

    $result->execute();

结果我收到了包含字段的单行表::number:company:user

我做错了什么?

非常感谢您的帮助!

2 个答案:

答案 0 :(得分:2)

您遇到的问题是您的绑定无法确定它应该与哪个占位符进行绑定。要更好地可视化,请考虑您正在生成的最终DBAL查询:

INSERT INTO `phonebook`(`number`, `company`, `user`) VALUES
(':number', ':company', ':user'),
(':number', ':company', ':user'),
(':number', ':company', ':user');

当您进行绑定时,您将同时替换所有参数,最后插入一行。

一种可能的解决方案是为每一行提供不同的参数名称,然后相应地替换每一个。 它看起来像这样:

public function randomParameterName()
{
    return uniqid('param_');
}

...

$parameters = [];
for ($i = 0; $i < count($data); $i++) {
    $parameterNames = [
        'number' => $this->randomParameterName(),
        'company' => $this->randomParameterName(), 
        'user' => $this->randomParameterName(),
    ];
    $parameters[$i] = $parameterNames;
    $inserted[] = sprintf("(':%s', ':%s', ':%s')",
        $parameterNames['number'], 
        $parameterNames['company'], 
        $parameterNames['user']
    );
}

$insertQuery = sprintf($insertQuery, implode(",", $inserted));
$result = $db->getConnection()->prepare($insertQuery);

foreach ($parameters as $i => $parameter) {
    $result->bindValue($parameter['number'], $data[$i]["number"]);
    $result->bindValue($parameter['company'], $data[$i]["company"]);
    $result->bindValue($parameter['user'], $data[$i]["user"]);
}

您可以扩展$data变量并将新参数名称合并到其中。这将消除另一个数组$parameters的需要,以保持对新创建的参数名称的引用。

希望这有帮助

答案 1 :(得分:0)

还有另一种选择:

$queryStart = "INSERT INTO {$tableName} (" . implode(', ', array_keys($buffer[0])) . ") VALUES ";
$queryRows = $params = $types = [];

foreach ($rowBuffer as $row) {
    $rowQuery =  '(' . implode(', ', array_fill(0, count($row), '?')) . ')';
    $rowParams = array_values($row);

    list($rowQuery, $rowParams, $types) = SQLParserUtils::expandListParameters($rowQuery, $rowParams, $types);

    $queryRows[] = $rowQuery;
    $params = array_merge($params, $rowParams);
}

$query = $queryStart . implode(', ', $queryRows);

$connection->executeQuery($query, $params, $types);