Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/233.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/67.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
通过PHP进行MySQL批量插入_Php_Mysql - Fatal编程技术网

通过PHP进行MySQL批量插入

通过PHP进行MySQL批量插入,php,mysql,Php,Mysql,在PHP中,我从URI中提取大量JSON数据,然后通过内置的JSON\u decode函数将其序列化到关联的PHP数组中 然后,我创建一个数组: $inserts = array(); 我在JSON关联数组中循环,为JSON数组中的每个项目向我的$inserts数组中添加一个新的键/值对: foreach($JSON_data as $key => $value) { $inserts[] = "(".mysql_real_escape_string($value["p

在PHP中,我从URI中提取大量JSON数据,然后通过内置的
JSON\u decode
函数将其序列化到关联的PHP数组中

然后,我创建一个数组:

$inserts = array();
我在JSON关联数组中循环,为JSON数组中的每个项目向我的
$inserts
数组中添加一个新的键/值对:

foreach($JSON_data as $key => $value) {     
    $inserts[] = "(".mysql_real_escape_string($value["prop1"]).","
                    .mysql_real_escape_string($value["prop2"]).","
                    .mysql_real_escape_string($value["prop3"]).")";
}
然后,我通过内爆我已经准备好的插入来执行批量插入:

mysql_query("INSERT INTO `MyTable` (`col1`,`col2`,`col3`) VALUES ".implode(",",$inserts));
无论如何,我发现不再建议使用
mysql.*
系列。所以我想知道,这种类型的模式是如何通过使用准备好的语句或w/e新接受的结构来实现的?我关心的是消除SQL注入,并尽可能快地用少于10个并发的、开放的连接(最好是1个)更新MySQL。同时,要让事情尽可能简单快捷


或者,如果有新的模式或首选方法来执行此类批量事务。

如果使用准备好的语句,则可以使用foreach循环遍历
$JSON_data
数组,并使用该数据块运行
INSERT

使用准备好的语句将减少构建查询的开销,只需在循环的每次迭代中将新数据发送到数据库

$query = mysqli_prepare("INSERT INTO `MyTable` (`col1`,`col2`,`col3`)
    VALUES(?,?,?)");

foreach($JSON_data as $key => $value) {
    $query->bind_param('sss',$value["prop1"],$value["prop2"],$value["prop3"];
    $query->execute();
}
请注意,
bind_param()
的第一个参数告诉它将绑定多少个值,以及每个值的类型。
s
对应字符串数据,
i
对应整数数据,
d
对应双精度浮点,
b
对应二进制数据

另一个警告,不要引用任何字符串数据,因为
s
数据类型告诉mysql需要一个字符串。如果在准备好的语句中引用
,它将告诉您参数的数量是错误的。如果您引用字符串,它将在mysql中被引用

编辑:

如果您想要使用相同的范例(通过一个查询插入多行),有几种方法可以做到这一点。一种方法是创建一个类来聚合
bind_参数
调用,并在执行查询时执行一个bind_参数。代码是。

使用或

下面是如何利用Mysqli中准备好的语句

<?php

//Basic layout to using parametized queries in PHP to prevent Bobby-tables

$VARIABLE = "Some Data";

$mysqli = new mysqli("SERVER","USER","PASSWORD","DATABASE");

$query = $mysqli->prepare("SELECT COLUMN_LIST FROM TABLE WHERE COLUMN = ?");
$query->bind_param('s',$VARIABLE); //'s' for string, use i for int d for double
$query->execute();

//Get results
$query->bind_result($VARIABLE_NAMES_MATCHING_COLUMN_NAMES_GO_HERE);
$query->fetch();

echo $VARIABLE_LIST_MATCHING_COLUMN_LIST;

?>


该块是否会在循环的每次迭代中阻塞?如果是这样的话,这会不会比单个查询花费更长的时间来完成(因为迭代次数接近一个很高的数字)?我不确定它是否会阻塞,但是如果你想使用多个
值()
列表,有一个类可以帮你做到这一点。只需使用循环或
str_repeat()
准备语句,然后在循环中使用
mbind_param()
,并延迟调用
execute()
,直到循环完成。这是最好的答案,但我决定采用另一种方法,使用注释过的
LOAD DATA infle
。@gcochard我认为即使使用链接到此处的类以及准备好的语句,也不能用一个查询插入多行。正如您所说,它将值和类型附加在一起。但要插入它们,您必须在准备好的语句(即nRows*N列)中包含相同数量的“?”。我尝试使用这个类并一次插入多行,但得到了以下警告:
PHP警告:mysqli_stmt::bind_param():变量的数量与prepared语句中的参数数量不匹配,因为我不清楚如何模仿这个。啊,我的错误。看来@Greg已经完全回答了上面的问题。顺便说一句,如果你想要真正快速的插入
LOAD DATA infle
很难打败。不过,我不建议在您的情况下使用它(如果您将数据作为JSON提取,那么它可能没有那么大),但是如果您需要同时向MySQL插入许多兆字节/千兆字节,请记住这一点。我修改了下面提到的类,在一个查询中插入多行(execute语句)。