Symfony2 + DBAL。如何使用 bindValue 进行多次插入?
Symfony2 + DBAL. How to use bindValue for multiple insert?
我正在使用 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();
结果我收到了一行 table 字段::number
、:company
、:user
.
我做错了什么?
非常感谢您的帮助!
您遇到的问题是您的绑定无法确定应该与哪个占位符进行绑定。为了更好地可视化它,请考虑您生成的最终 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
来保存对新创建的参数名称的引用。
希望对您有所帮助
还有一个选择:
$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);
我正在使用 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();
结果我收到了一行 table 字段::number
、:company
、:user
.
我做错了什么?
非常感谢您的帮助!
您遇到的问题是您的绑定无法确定应该与哪个占位符进行绑定。为了更好地可视化它,请考虑您生成的最终 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
来保存对新创建的参数名称的引用。
希望对您有所帮助
还有一个选择:
$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);