简体   繁体   English

如何使用准备好的语句插入多行

[英]How to insert multiple rows using prepared statements

I use a very simple insert statement我使用了一个非常简单的插入语句

INSERT INTO table (col1, col2, col3) VALUES (1,2,3), (4,5,6), (7,8,9), ...

Currently, the part of the query that holds the values to be inserted is a separate string constructed in a loop.目前,保存要插入值的查询部分是在循环中构造的单独字符串。

How can I insert multiple rows using a prepared statement?如何使用准备好的语句插入多行?

edit : I found this piece of code.编辑:我找到了这段代码。 However, this executes a seperate query for every row.但是,这会为每一行执行单独的查询。 That is not what I am looking for.那不是我要找的。

$stmt =  $mysqli->stmt_init();
if ($stmt->prepare("INSERT INTO table (col1, col2, col3) VALUES (?,?,?)")){ 
    $stmt->bind_param('iii', $_val1, $_val2, $_val3);
    foreach( $insertedata as $data ){
        $_val1 = $data['val1'];
        $_val2 = $data['val2'];
        $_val3 = $data['val3'];
        $stmt->execute();
    }
}

edit#2 : My values come from a multidimensional array of variable length.编辑#2 :我的值来自可变长度的多维数组。

$values = array( array(1,2,3), array(4,5,6), array(7,8,9), ... );

This is normally only a technique that I use when I am writing a prepared statement for a query that contains an IN clause.这通常只是我在为包含IN子句的查询编写准备好的语句时使用的一种技术。 Anyhow, I've adapted it to form a single prepared query (instead of iterated prepared queries) and I tested it to be successful on my server.无论如何,我已经将其调整为形成单个准备好的查询(而不是迭代的准备好的查询),并在我的服务器上对其进行了测试以使其成功。 The process is a bit convoluted and I don't know if there will ever be any advantage in speed (didn't benchmark).这个过程有点复杂,我不知道在速度上是否会有任何优势(没有基准)。 This really isn't the type of thing that developers bother with in production.这真的不是开发人员在生产中烦恼的事情类型。

In the following snippet, the number of columns to be inserted with each row is known.在下面的代码片段中,每行要插入的列数是已知的。 For this reason, there is a "magic" 3 and a ?,?,?出于这个原因,有一个“魔法” 3和一个?,?,? hardcoded.硬编码。

...array_merge(...$rows) is used to flatten then unpack the payload of values. ...array_merge(...$rows)用于展平然后解压值的有效载荷。

For researchers that are dealing with string type values, just change the i to s .对于处理字符串类型值的研究人员,只需将i更改为s (When in doubt, use s for everything that is not BLOB.) (如有疑问,请对不是 BLOB 的所有内容使用s 。)

Tested/Working Code:测试/工作代码:

$rows = [[1, 2, 3], [4, 5, 6], [7, 8, 9]];  // sample indexed array of indexed arrays
$rowCount = count($rows);
$values = "(" . implode('),(', array_fill(0, $rowCount, '?,?,?')) . ")";

$conn = new mysqli("localhost", "root", "", "myDB");
$stmt = $conn->prepare("INSERT INTO test (col1, col2, col3) VALUES $values");
$stmt->bind_param(str_repeat('i', $rowCount * 3), ...array_merge(...$rows));
$stmt->execute();

There is also nothing wrong with using a prepared statement with a single row of placeholders and executing the query one row at a time in a loop.使用带有一行占位符的准备好的语句并在循环中一次一行执行查询也没有错。


For anyone looking for similar dynamic querying techniques:对于任何正在寻找类似动态查询技术的人:

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM