Как сделать & ldquo; вставить несколько строк & rdquo; более эффективны и конвертируются в mysqli? [Дубликат]

Это DataKinds в действии, которое:

  • поднимает значения на уровне уровня, а
  • поднимает типы до уровня уровня

Это, однако, вызывает путаницу на уровне типа. Теперь в типах [X] может быть либо [X] :: *, либо тип списка X, либо вместо этого мы могли бы иметь [X] :: [T] из-за подъема - это значение [X] (только список, содержащий только единственное значение X) с X типа T, поднятое на уровне уровня.

Чтобы преодолеть эту двусмысленность, GHC требует цитаты перед конструкторами с поднятыми значениями. Итак, у нас есть [X] :: * и '[X] :: [T].

Конкретно, в вашем случае Get '[JSON] [User] включает как значение списка [JSON], поднятое до уровня типа, так и тип списка [User] , Чтобы лучше понять разницу, обратите внимание, что терминов типа '[JSON] нет, поскольку это не тип списка. Мы могли бы даже иметь Get '[JSON,JSON,JSON] [User] как хорошо выраженное выражение или даже Get '[] [User]. Вместо этого мы не можем иметь Get '[JSON] [User,User], так как [User,User] не является типом.

(Тип Get '[JSON,JSON,JSON] [User], даже если он действителен, не может быть осмысленно использован библиотекой Servant. не знаю, для чего этот поднятый список используется в Слуге.)

5
задан jiaweizhang 21 November 2015 в 11:19
поделиться

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 - Оптимизированный

Подготовленные операторы и множественные вставки объединяют производительность, которая почти идентична запросам сырой вставки метода 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()).
12
ответ дан fyo 21 August 2018 в 15:17
поделиться
  • 1
    Это именно то, что я пытался ИЗБЫТЬ, как я уже сказал, я хотел просто передать запрос, БЕЗ делать лишние фанки в PHP, и это экстремальный пример фанковых вещей, другими словами, я хотел передать запрос как насколько это возможно на его исходной форме. – user1675155 4 October 2016 в 09:20
  • 2
    @fyo, но как бы вы справились с Method1 или Method2, если Data not хранится в массиве , но в объекте JSON ? Как разрезать сотни или тысячи наборов данных JSON на куски 10, чтобы вставить их сразу? – Peter 14 September 2017 в 19:48

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

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

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

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

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

затем связывают все значения с помощью call_user_func_array() и, наконец, execute;

-3
ответ дан Your Common Sense 21 August 2018 в 15:17
поделиться
  • 1
    Ладно, я думаю, я могу это сделать. весь запрос был фактически подготовлен с помощью php, поэтому это был бы длинный одиночный запрос, но я предполагаю, что мне нужно изменить его для соответствия mysqli. Не хотел делать лишние вещи только для вставки, но я думаю, что мне нужно приспособиться к mysqli. Спасибо, отличный ответ. – user1675155 22 October 2013 в 09:40
  • 2
    Вы не ответили на его вопрос. Как вставить этот запрос в mysqli? ... – karmafunk 22 October 2013 в 09:56
  • 3
    Нашел аналогичный вопрос: stackoverflow.com/questions/15575405/… , но до сих пор нет решения !!!! – user1675155 22 October 2013 в 18:45
Другие вопросы по тегам:

Похожие вопросы: