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

问题描述 投票:0回答:2

我正在使用 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

我做错了什么?

非常感谢您的帮助!

php symfony dbal
2个回答
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
投票

还有另一种选择:

$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);
© www.soinside.com 2019 - 2024. All rights reserved.