Перейти до вмісту
Пошук в
  • Детальніше...
Шукати результати, які ...
Шукати результати в ...

Множественный INSERT INTO в подготовленном запросе PDO


Recommended Posts

Добрый день. Подскажите, как правильно выполнить множественный запрос на запись данных использую PDO и подготовленный запрос.

Вот код

Скрытый текст
$resultQuery = $this->db->prepare($query);

if ($queryParam) {
    foreach ($queryParam as $key => $valueParam) {
       foreach ($valueParam as $param => &$dataParam) {
          $resultQuery->bindParam(":$param", $dataParam['data'], $dataParam['type']);
       }
    }
}

$resultQuery->execute();

 

Данные формирует данный метод:

Скрытый текст
private static function insertOrderProduct($productData, $orderId)
    {
        if (!empty($productData) || !empty($orderId)) {
            $db = Registry::get('db');
            $query = 'INSERT INTO orders_product ( '
                . 'order_id, product_id, quantity'
                . ') VALUES ( '
                . ':order_id, '
                . ':product_id, '
                . ':quantity '
                . ')';
            foreach ($productData as $key => $product) {
                $queryParam[] = array(
                    'order_id' => array(
                        'data' => $orderId,
                        'type' => PDO::PARAM_STR
                    ),
                    'product_id' => array(
                        'data' => $product['product_id'],
                        'type' => PDO::PARAM_STR
                    ),
                    'quantity' => array(
                        'data' => $product['quantity'],
                        'type' => PDO::PARAM_STR
                    )
                );
            }
            $db->query($query, $queryParam);
        }
    }

 

Вот массив, который он формирует:

Скрытый текст
Array
(
    [0] => Array
        (
            [order_id] => Array
                (
                    [data] => 116
                    [type] => 2
                )

            [product_id] => Array
                (
                    [data] => 66
                    [type] => 2
                )

            [quantity] => Array
                (
                    [data] => 1
                    [type] => 2
                )

        )

    [1] => Array
        (
            [order_id] => Array
                (
                    [data] => 116
                    [type] => 2
                )

            [product_id] => Array
                (
                    [data] => 65
                    [type] => 2
                )

            [quantity] => Array
                (
                    [data] => 1
                    [type] => 2
                )

        )

    [2] => Array
        (
            [order_id] => Array
                (
                    [data] => 116
                    [type] => 2
                )

            [product_id] => Array
                (
                    [data] => 64
                    [type] => 2
                )

            [quantity] => Array
                (
                    [data] => 1
                    [type] => 2
                )

        )

)

 

Структура таблицы:

Скрытый текст

1.thumb.png.cdb212344644ff5bebe7a1fbda4167e7.png

Проблема заключается в том, что в таблицу залетает только первая запись.

 

Надіслати
Поділитися на інших сайтах

Что в параметрах делает data и type?

Почему массив вместо строки в параметры пускаете?

 

Ещё можно заменить драйвер и попробовать запрос написать, как для mysql

https://github.com/opencart/opencart/blob/master/upload/system/library/db/pdo.php

 

Тут в примере нет никаких data и type

https://phpdelusions.net/pdo_examples/insert

Надіслати
Поділитися на інших сайтах

@buslikdrev Массив содержит ключ, который равен именованному указателю в самом запросе. Пример  :order_id Ключ 'data' => переменная со со значением, которое необходимо вставить в запрос, ключ 'type' => тип значение (PDO::PARAM_INT или PDO::PARAM_STR). Если не указать тип значения, то запрос в который передаётся значение переменной (int), вызывает ошибку, требуя явно указать тип значения. Данная задача не относиться на прямую к OpenCart. Но в в версии OpenCart 2.3 это реализовано так:

Скрытый текст
public function bindParam($parameter, $variable, $data_type = \PDO::PARAM_STR, $length = 0) {
		if ($length) {
			$this->statement->bindParam($parameter, $variable, $data_type, $length);
		} else {
			$this->statement->bindParam($parameter, $variable, $data_type);
		}
	}

 

 

Надіслати
Поділитися на інших сайтах

В общем, насколько я понял, с PDO и подготовленным запросом, много строк за одну транзакцию не вставить. В цикле можно передавать параметры только для одной строки, затем фиксировать. Такой трюк работает только с msqli. Вопрос закрыт.

P.S. В коде есть ошибка, execute() вынесен из цикла...

Надіслати
Поділитися на інших сайтах

а в чем трудность написать свой запрос (не в рамках PDO и выполнить

или так

$data = [
    ['aaa','nnn', 'xxx'],
    ['bbb','mmm', 'yyy']
];
$query = $pdo->prepare("INSERT INTO table (f1, f2, f3) VALUES (?,?,?)");
foreach ($data as $row) {
        $query->execute($row);
}

@buslikdrev дал ссылку на пример

Надіслати
Поділитися на інших сайтах

09.04.2022 в 18:36, chukcha сказал:

а в чем трудность написать свой запрос (не в рамках PDO и выполнить

или так

$data = [
    ['aaa','nnn', 'xxx'],
    ['bbb','mmm', 'yyy']
];
$query = $pdo->prepare("INSERT INTO table (f1, f2, f3) VALUES (?,?,?)");
foreach ($data as $row) {
        $query->execute($row);
}

@buslikdrev дал ссылку на пример

Я уже понял. Так примерно и сделал. Просто не до конца разобрался. Думал что $query->execute($row); нет необходимости выполнять в цикле. Хотел этого избежать, т.к. в будущем планировал запись большого количества строк в бд. 

При использовании mysqli использовал данный способ:

$query = ""INSERT INTO table (f1, f2, f3) VALUES ";

foreach ($data as $key => $value) {

    $query .= '(' . $value['f1'] . ',' . $value['f2] . ',' . $value['f3] . '),';

}

Это давало мне необходимую производительность. 

Надіслати
Поділитися на інших сайтах

09.04.2022 в 21:06, mario512 сказал:

$query = ""INSERT INTO table (f1, f2, f3) VALUES ";

foreach ($data as $key => $value) {

    $query .= '(' . $value['f1'] . ',' . $value['f2] . ',' . $value['f3] . '),';

}

Это давало мне необходимую производительность. 

можно и для PDO так сделать

 

Надіслати
Поділитися на інших сайтах

09.04.2022 в 21:08, chukcha сказал:

можно и для PDO так сделать

 

Да, но насколько я понял, если не использовать подготовленный запрос. Просто придётся накидать дополнительно новый метод для такого случая)

Надіслати
Поділитися на інших сайтах

пробуйте

Зачем вам подготовленный запрос для инсерта?

Я могу понять подготовленный для множественных селектов (getProduts + getProduct), когда не будет потрачено время на план запроса
 

Надіслати
Поділитися на інших сайтах

09.04.2022 в 21:34, chukcha сказал:

пробуйте

Зачем вам подготовленный запрос для инсерта?

Я могу понять подготовленный для множественных селектов (getProduts + getProduct), когда не будет потрачено время на план запроса
 

Да в принципе на данном этапе просто пытаюсь оптимизировать скрипт для заливки товаров на сайт. Мысль уловил. Огромное спасибо. Харьков - Держитесь!

Надіслати
Поділитися на інших сайтах

09.04.2022 в 21:59, mario512 сказал:

пытаюсь оптимизировать скрипт для заливки

Да, сделав множественный  инсерт, вы действительно ускорите выполнение
Но!!!
не забывайте, что есть еще индексация (перестройка), что есть не малое время

Предлагаю проверить гипотезу

лок таблицы
отключение индексов
инсерт
влючаем
анлок
 

Надіслати
Поділитися на інших сайтах

Створіть аккаунт або увійдіть для коментування

Ви повинні бути користувачем, щоб залишити коментар

Створити обліковий запис

Зареєструйтеся для отримання облікового запису. Це просто!

Зареєструвати аккаунт

Вхід

Уже зареєстровані? Увійдіть тут.

Вхід зараз
  • Зараз на сторінці   0 користувачів

    • Ні користувачів, які переглядиють цю сторінку

×
×
  • Створити...

Important Information

На нашому сайті використовуються файли cookie і відбувається обробка деяких персональних даних користувачів, щоб поліпшити користувальницький інтерфейс. Щоб дізнатися для чого і які персональні дані ми обробляємо перейдіть за посиланням . Якщо Ви натиснете «Я даю згоду», це означає, що Ви розумієте і приймаєте всі умови, зазначені в цьому Повідомленні про конфіденційність.