Mysqli多行插入,简单的多插入查询

时间:2013-10-22 08:13:10

标签: php mysql database mysqli

如何使用mysqli插入此查询?...

INSERT INTO table (field1, field2, field3) VALUES ('value', 'value', 'value'), ('value', 'value', 'value'), ('value', 'value', 'value');

通常在mysql中这个查询是直截了当的并且会插入3行,如何在不使用预准备语句的情况下在mysqli中执行此操作,或者使用预准备语句但不会过于复杂?我只是想知道是否有办法执行这样的查询而不用在PHP中做更多的时髦的东西。

本质上,我有一些提取的数据,每个插入大约有10行(除了有多行之外还需要多个插入),这就是我需要的。我只希望用查询来执行此操作,因为我通常使用mysql完成它,而不是每行添加多个插入。

2 个答案:

答案 0 :(得分:14)

mysqli类提供了许多不同的方法来完成插入,每种方法都有其自身的优点。当然,其中一个应该符合您的需求。

以下示例假设您未指定的“提取数据”存储在数组数组中:$ bigArray [0 ... datasetsize] [0 ... 2]。

假设mysqli数据库为$ db。

方法1 - 旧学校

您可以通过简单地构建查询字符串并使用它查询数据库来直接执行此操作。如您所指定,插入一次捆绑10个。下面的代码显示了一个这样的bundle,并且可以简单地扩展到整个数据集(bigArray)。数据应该使用mysqli :: escape_string进行转义(此​​处未完成)。

在所有示例中,假设要插入的数据是整数。

$sql = "INSERT INTO testTable (fieldA, fieldB, fieldC) VALUES ";
for ($i = 0; $i < 10; ++$i)
{
    if ($i > 0) $sql .= ", ";
    $sql .= "({$bigArray[$i][0]}),({$bigArray[$i][1]}),({$bigArray[$i][2]})";
}
$db->query($sql);

方法2 - 尽可能简单

如果要使用预准备语句和参数绑定,则第一项工作可能如下所示。虽然不是最佳,但声明只准备一次。但是,每个插入的变量都是绑定的,这很浪费(但很简单)。由于插入没有捆绑,因此示例循环超过10。

$statement = $db->prepare("INSERT INTO testTable (fieldA, fieldB, fieldC) VALUES (?,?,?)");
for ($i = 0; $i < 10; ++$i)
{
    $statement->bind_param("iii",$bigArray[$i][0],$bigArray[$i][1],$bigArray[$i][2]);
    $statement->execute();
}

方法3 - 优化

准备语句和多个插入组合使得性能几乎与方法1的原始插入查询相同。实际结果将根据您的设置而有所不同,但是对我的系统进行快速测试,同时使用本地和远程数据库显示性能使用优化方法更快几个百分点,如果方法1中的数据需要转义,则会增加几个点。

以下使用call_user_func_array,但如果您知道每次要捆绑多少插入并直接构建调用bind_param,则可以避免这种情况。这将进一步提高绩效。

为清楚起见,这个例子包括外部循环并假设要插入总共10k行(即bigArray [0..9999] [0..2])。

$sql = "INSERT INTO testTable (fieldA,fieldB,fieldC) VALUES (?,?,?)".str_repeat(",(?,?,?)",9);
$statement = $db->prepare($sql);

// This is the type string used by statement::bind_param. 
// Example assumes all INTs.
$types = (array)str_repeat("i",30);

$values = array_fill(0,30,0); // A bit of unneeded variable init.

// * See notes following code snippet on why the intermediate array is used.
$intermediate = array();
for ($n = 0; $n < 30; ++$n)
{
    $intermediate[$n] = &$values[$n];
}

call_user_func_array(array(&$statement, "bind_param"), array_merge($types,$f));

for ($j = 0; $j < 1000; ++$j)
{
    for ($i = 0; $i < 10; ++$i)
    {
        $values[$i*3] = $bigArray[$i][0];
        $values[$i*3+1] = $bigArray[$i][1];
        $values[$i*3+2] = $bigArray[$i][2];
    }
    $statement->execute();
}

// call_user_func_array with bind_param requires the values be 
// passed by reference which is evaluated only on the initial 
// call. Using $values[...] = &$bigArray[...] below won't work
// and an intermediate array referencing $values is used. This 
// bit of "extra funky stuff" can be avoided at a very slight 
// performance penalty by setting $values[...] = $bigArray[...] 
// AND EVALUATING EACH TIME (move call_user_func_array
// inside the outer loop, i.e. right above $statement->execute()).

答案 1 :(得分:-3)

Mysqli不是它自己的数据库,只是一组用于在旧的mysql中发送查询的函数。

因此,使用mysqli可以运行任何mysql查询。

但是,在动态提供的值的情况下,您无法避免“PHP中的额外时髦的东西”,因为您应该使用准备好的语句。并且,不幸的是,原始的mysqli与他们并不那么容易。

因此,要执行此类插入,您需要先创建一个带占位符的查询

INSERT INTO表(field1,field2,field3)VALUES(?,?,?),(?,?,?),(?,?,?);

然后使用call_user_func_array()来绑定所有值 最后execute;