Многословная вставка 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 – как можно проще

Если вы хотите использовать подготовленный оператор и привязку параметров, первое усилие может выглядеть следующим образом. Хотя это и не является оптимальным, утверждение готовится только один раз. Однако переменные привязаны к каждой вставке, которая является расточительной (но простой). Поскольку вставки не связаны, пример повторяется более 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, ie right above $statement->execute()). 

Mysqli не является собственной базой данных, а просто набором функций для отправки запроса в старой mysql.

Таким образом, используя mysqli, вы можете запустить любой запрос mysql.

Тем не менее, в случае динамически поставляемых значений вы не можете избежать «лишних фанк-файлов в PHP», так как вы должны использовать для этого подготовленные инструкции . И, к сожалению, raw mysqli с ними не так просто.

Итак, чтобы выполнить такую ​​вставку, вам нужно сначала создать запрос с заполнителями

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

затем привяжите все значения, используя call_user_func_array()
и, наконец, execute ;

Вам не нужно использовать подготовленные инструкции, если вы уже создали свой SQL-запрос.

 $result = $mysqli->query($sql_query); while( $row = $result->fetch_array(MYSQLI_ASSOC) ) { $rows[]=$row; } 

Убедитесь, что вы следите за SQL-инъекцией, но если вы подготовили свое заявление, я предполагаю, что вы уже это сделали.

Для вставки:

 $query = "INSERT INTO myCity VALUES (NULL, 'Stuttgart', 'DEU', 'Stuttgart', 617000)"; $mysqli->query($query); printf ("New Record has id %d.\n", $mysqli->insert_id);