Проблема с записью в MySQL PHP

200
21 июня 2017, 01:44

В ходе работы программы получаю массив arr на 1000 значений, хочу записать в базу, используя PDO

выводит: Warning: Error while sending QUERY packet. PID=8448

foreach ($arr as $v => $k){
    $sql = "INSERT INTO table (value, key) VALUES (:value, :key);
    $data = [
        ":value" => $v;
        ":key"   => $k
    ];
    $db->query($sql,$data);
};

Так же пробовал разбить по 25 и 50 запросов:

$sql = "";
$i = 0;
foreach ($arr as $k => $v) {
    $i++;
    if ($i % 50 == 0){
        $db->query($sql);
        sleep(5);
        $sql = "";
    }
    $sql .= "INSERT INTO table(link,price) VALUES ('" . $k . "','" . $v . "'); ";
}
$db->query($sql);

выводит:

Warning: PDOStatement::execute(): MySQL server has gone away in ....\Connection.php on line 53

Класс Connection:

....
public function query(string $sql, array $data = [])
{
    51 set_time_limit(0);
    52 $sth = $this->link->prepare($sql);
    53 $sth->execute($data);
    54 $result = $sth->fetchAll();
    55 if (false === $result) {
        return [];
    }
    return $result;
}

По итогу в базу ничего не записывается. Пробовал с меньшими значениями (~70-80) всё залетает нормально, помогите решить проблему. Openserver MySQL 5.5 PHP7

UPDATE: Ошибку MySQL server has gone away in ... решило небольшое дополнение к классу подключения:

$this->link = new \PDO($dns, $config['***'], $config['***']);
$this->link->query("SET wait_timeout=9999;");

query("SET wait_timeout=9999;");

Answer 1

Для повышения производительности Вы можете использовать один INSERT с несколькими VALUES:

INSERT INTO table (x,y,z) VALUES(1,2,3),(1,2,3),(1,2,3);

А то так у вас формируется столько же запросов, сколько элементов в массиве.

INSERT и VALUES нужно также делить на блоки! И больше 1024 записей в один INSERT добавлять не стоит

function placeholders($text, $count=0, $separator=","){
    $result = array();
    if($count > 0){
        for($x=0; $x<$count; $x++){
            $result[] = $text;
        }
    }
    return implode($separator, $result);
}

By @HerbertBalagtas

foreach($arr as $k){
    $arrValues = array_merge($arrValues, array_values($k));
    $sumParams[] = '('.placeholders('?', sizeof($k)).')';
}

В запросе в VALUE, подставляйте знаки вопроса '?'.

"INSERT INTO table(link,price) VALUES " . implode(',', $sumParams);

После этого, $arrValues подставьте в execute($arrValues)

READ ALSO
mxnet Ошибка при вызове любой функции &ldquo;Cannot find pass &hellip; in the registry&rdquo; [требует правки]

mxnet Ошибка при вызове любой функции “Cannot find pass … in the registry” [требует правки]

Собрал из исходников в VS2013 на Win7Примеры для С++ пробую и такая ошибка "Cannot find pass

278
C++ WinApi Буфер обмена

C++ WinApi Буфер обмена

Нужно достать картинку из буфера и вывести ее на экранЯ написал код:

315
Почему не работает запрос в QSqlTableModel?

Почему не работает запрос в QSqlTableModel?

Хочу оббежать таблицу с моделью QSqlTableModel, все сделал как в книге Шлее, но id=0, lin="", domen="":

265
Не могу получить значение из шаблонного массива

Не могу получить значение из шаблонного массива

В мэйне я его объявляю как MyArray *a = new MyArray();Но при попытке присвоить по индексу (int b = a[0]) получаю ошибку

278