mysqli多行插入,简单多插入查询

Posted

技术标签:

【中文标题】mysqli多行插入,简单多插入查询【英文标题】:Mysqli multiple row insert, simple multi insert query 【发布时间】:2013-10-31 00:09:08 【问题描述】:

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

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

通常在 mysql 中,这个查询是直截了当的,将插入 3 行,我如何在 mysqli 中执行此操作而不使用准备好的语句,或者使用准备好的语句但不会变得太复杂?我只是想知道是否有一种方法可以执行这样的查询,而无需在 php 中做额外的时髦的事情。

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

【问题讨论】:

mysqli 只是在 mysql 中发送查询的一组函数。 将 SQL 语句存储在变量中,并将其作为参数传递给 mysqli_query; Sajuna 很遗憾不能那样做。 mysqli和mysql不一样。 在 mysqli 连接打开的情况下尝试使用 mysql,但没有用! 【参考方案1】:
$sql = "INSERT INTO `aspnetuserroles` (`UserId`, `RoleId`)
         VALUES ('1', '8811404'), ('1', '1429d')";
$stmt = mysqli_prepare($conn, $sql); 

  if (mysqli_stmt_execute($stmt)) 
       echo '<script language="javascript">';
       echo 'alert("Registeration Sucessfull!")';
       echo '</script>';
     
      else 
             echo '<script language="javascript">';
             echo 'alert("User Role Registeration Failed!")';
             echo '</script>';
             echo $sql;
                             

【讨论】:

【参考方案2】:

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 - 尽可能简单

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

Prepared statements 和多个 insert 组合使性能几乎与方法 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 中做额外的时髦的东西,这是时髦东西的极端例子,在其他换句话说,我想尽可能多地以原始形式传递查询。 @fyo 但是如果数据存储在 array 中,而是存储在 JSON 中,您将如何处理 Method1 或 Method2 对象?如何将成百上千的 JSON 数据集分割成 10 个片段以一次插入? 答案中的 $f 是什么?【参考方案3】:

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

所以,使用 mysqli 你可以运行任何 mysql 查询。

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

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

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

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

【讨论】:

好吧,我想我能做到。整个查询实际上是用 php 准备的,所以这将是一个很长的单个查询,但我想我必须修改它以适应 mysqli。不想为插入做额外的事情,但我想我必须适应 mysqli。谢谢!,很好的答案。 发现了一个类似的问题:***.com/questions/15575405/…但还是没有解决办法!!!

以上是关于mysqli多行插入,简单多插入查询的主要内容,如果未能解决你的问题,请参考以下文章

MySQLi:使用一个准备好的语句插入多行

MySQLi - 插入多行 - 空 POST 数组

在单个 INSERT 查询中插入多行会保证顺序自动递增主键吗?

如何在mysql中将单行插入查询重构为多行插入查询?

Oracle中的多行插入查询(从一张表中选择多行并插入到另一张表中[重复]

使用单个查询插入多行时获取所有插入的 ID