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

标签 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 那样使用查询来执行此操作,而不是每行添加多个插入。

最佳答案

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

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

假定 mysqli 数据库为 $db。

方法 1 - 老派

您可以像往常一样直接进行操作,只需构建查询字符串并使用它查询数据库即可。按照您的指定,插入物一次捆绑 10 个。以下代码显示了一个这样的包,并被简单地扩展到整个数据集 (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 - 越简单越好

如果您想使用准备好的语句和参数绑定(bind),第一步可能如下所示。虽然不是最优的,但语句只准备一次。但是,变量是为每个插入绑定(bind)的,这很浪费(但很简单)。由于插入未捆绑,因此该示例循环超过 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()).

关于php - Mysqli 多行插入,简单的多插入查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19512498/

相关文章:

mysql - 如何知道一组日期范围是否涵盖更大的日期范围?

android - 实现社交登录和应用内登录

php - 在 php 中循环以选定前缀开头的 mysql 数据库名称

php - 必须插入varchar时如何将数组插入MySQL

JavaScript 未按顺序运行

mysql - 在MySql自定义函数中选择最后一项

java - 即时刷新数据库配置

PHP session 在index.php 上不存在

php - 获取当前域

mysql - 非原子行为 Eclipselink-半提交的数据库事务