5

我有一个帖子的数组:

//this are arrays
$name    = $_POST["name"];
$age     = $_POST["age"];
$date    = $_POST["date"];

我在 PDO 中有一个插入查询:

$stmt = $db->prepare("INSERT INTO staff (name, age, address) VALUES (:name, :age, :address)");

我的问题是如何使用 php 生成/或实现查询,如下所示:

INSERT INTO staff (name, age, address) VALUES
($name[0], $age[0], $address[0]), ($name[1], $age[1], $address[1])... etc

我尽量保持服务器负载低。

4

4 回答 4

3

您可以准备适当的声明,例如:

$sql = "INSERT INTO staff (name, age, address) VALUES ";
$values = array();

for ($i = 1; $i <= $count; $i++) {
  $values[] =  "(:name$i, :age$i, :address$i)"
}

$stmt = $db->prepare($sql . implode(', ', $values));

但是,恕我直言,您可能会很好地遍历每组值。对服务器来说负担不大,而且你的代码会更简单。

于 2013-05-05T12:46:03.077 回答
3

准备好的语句是不可能的。

如果要在一个查询中插入可变数量的记录,则必须动态生成 SQL 查询,这使得事先无法准备

如果您使用数据库驱动程序的escape_string功能(quote()适用于 MySQL),那么您可以构建查询并仍然获得准备好的语句为您提供的安全性。

$query = "INSERT INTO table (a, b, c) VALUES";
$tuple = " ('%s', '%s', '%s'),";
foreach ($items as $item) {
    $a = $db->quote($item['a']);
    $b = $db->quote($item['b']);
    $c = $db->quote($item['c']);
    $query .= sprintf($tuple, $a, $b, $c);
}
$query = rtrim($query, ","); // Remove trailing comma
// Use the query...

附录:

如果您使用准备好的语句,那么您可以单独插入记录,而不必担心一次性插入它们。这实际上是准备好的陈述的重点。

与良好的旧 SQL 查询不同,后者是一步过程,只是被发送然后被遗忘......

$db->query("INSERT INTO table (a, b, c) VALUES ('a', 'b', 'c')");

...准备好的陈述是一个两步的过程。

首先,您创建准备好的语句。然后这个语句被发送到数据库,告诉它“这是你应该期待的”。数据库通常还会优化查询以使其更快。然后,此步骤会返回一个语句句柄(通常$stmt在 PHP 文档中调用)。

$stmt = $db->prepare('INSERT INTO table (a, b, c) VALUES (:a, :b, :c)');

其次,使用此句柄,您可以继续插入内容:

foreach ($records as $record) {
    $stmt->execute(array(
        ':a' => $record['a'],
        ':b' => $record['b'],
        ':c' => $record['c'],
    ));
}

因为数据库已经知道会发生什么,它可以优化INSERTs 的速度,这意味着您不必经历我在本附录上面提到的内容。

维基百科实际上有一个相当不错的准备好的陈述。

于 2013-05-05T12:46:49.570 回答
1

如果你使用 PDO,你应该准备你的语句,并用不同的值执行它:

$stmt = $db->prepare("INSERT INTO staff (name,age,address) VALUES (:name,:age,:address)");

for($i=0;$i<count($name);$i++)
{
    $stmt->execute(array(
        ":name" => $name[$i],
        ":age" => $age[$i],
        ":address" => $address[$i]));
}

但是,如果您想将其放入单个查询中,则应使用 $db-> exec ()

$query = "INSERT INTO staff (name,age,address) VALUES ";
$values = array();

for($i=0;$i<count($names);$i++)
{
    array_push($values, "('" . $name[$i] . "','" . $age[$i] . "','" . $address . "')");
}

$db->exec($query . implode("," . $values));

请注意,与 prepare 和 execute 方法相反,此方法易受攻击,因为它不验证输入

于 2013-05-05T13:19:03.193 回答
0

delayed关键字添加到 insert ( insert delayed ...) 以减少服务器负载,并且只需循环使用所有值的准备好的语句。insert如果你做了一大堆插入,MySQL 无论如何都会在内部将它作为单独的语句排队,扩展语法只是语法糖。

于 2013-05-05T12:47:45.840 回答