wpdb->вставить несколько записей одновременно

Вопрос или проблема

Так что после того, как я создал таблицу ‘settings-table’, я хочу добавить в нее несколько записей.

Вот как я хочу это сделать, это не лучший способ, поэтому мне нужен более лучший способ сделать это, потому что я добавлю больше записей в таблицу.

ПРИМЕР 1

 $wpdb->insert('settings-table', array('option_name'   => 'name-1', 
                                       'option_value'  => 'val-1', 
                                       'option_created'=> current_time('mysql'),
                                       'option_edit'   => current_time('mysql'),
                                       'option_user'   => 'user-1' 
                                       ));    
 $wpdb->insert('settings-table', array('option_name'   => 'name-2', 
                                       'option_value'  => 'val-2', 
                                       'option_created'=> current_time('mysql'),
                                       'option_edit'   => current_time('mysql'),
                                       'option_user'   => 'user-2' 
                                       ));
 $wpdb->insert('settings-table', array('option_name'   => 'name-1', 
                                       'option_value'  => 'val-3', 
                                       'option_created'=> current_time('mysql'),
                                       'option_edit'   => current_time('mysql'),
                                       'option_user'   => 'user-3' 

ОБНОВЛЕНИЕ

это работает (любые другие лучшие решения приветствуются)

$wpdb->query("INSERT INTO settings-table
            (`option_name`, `option_value`, `option_created`, `option_edit`, `option_user`)
            VALUES
            ('name-1', 'val-1', current_time('mysql'), current_time('mysql'), 'user-1'),
            ('name-2', 'val-2', current_time('mysql'), current_time('mysql'), 'user-2'),
            ('name-3', 'val-3',  current_time('mysql'), current_time('mysql'), 'user-3')")

$wpdb->query("INSERT INTO settings-table
            (option_name, option_value, option_created, option_edit, option_user)
            VALUES
            ('name-1', 'val-1', current_time('mysql'), current_time('mysql'), 'user-1'),
            ('name-2', 'val-2', current_time('mysql'), current_time('mysql'), 'user-2'),
            ('name-3', 'val-3',  current_time('mysql'), current_time('mysql'), 'user-3')")

В запросе, который вы опубликовали, названия столбцов не должны быть в строке.

$wpdb->insert функция не поддерживает вставку нескольких записей за один вызов функции. Вам нужно пройтись по вашим данным и подготовить данные для вставки, а затем использовать $wpdb->insert в цикле и вставлять записи одну за другой.

Вместо этого мы можем подготовить запрос вставки следующим образом и выполнить запрос всего один раз.

Итак, если мы хотим вставить 100 записей, нам нужно выполнить 100 запросов вставки, если мы хотим использовать $wpdb->insert. А если мы используем следующий код, нам нужно выполнить только 1 запрос вставки.

Надеюсь, это поможет.

function do_insert($place_holders, $values) {

    global $wpdb;

    $query           = "INSERT INTO settings-table (`option_name`, `option_value`, `option_created`, `option_edit`, `option_user`) VALUES ";
    $query           .= implode( ', ', $place_holders );
    $sql             = $wpdb->prepare( "$query ", $values );

    if ( $wpdb->query( $sql ) ) {
        return true;
    } else {
        return false;
    }

}

$data_to_be_inserted = array( array(
    'option_name'   => 'name-1', 
    'option_value'  => 'val-1', 
    'option_created'=> current_time('mysql'),
    'option_edit'   => current_time('mysql'),
    'option_user'   => 'user-1' 
),

array(
    'option_name'   => 'name-2', 
    'option_value'  => 'val-2', 
    'option_created'=> current_time('mysql'),
    'option_edit'   => current_time('mysql'),
    'option_user'   => 'user-2' 
),
array(
    'option_name'   => 'name-1', 
    'option_value'  => 'val-3', 
    'option_created'=> current_time('mysql'),
    'option_edit'   => current_time('mysql'),
    'option_user'   => 'user-3'
));

$values = $place_holders = array();

if(count($data_to_be_inserted) > 0) {
    foreach($data_to_be_inserted as $data) {
        array_push( $values, $data['option_name'], $data['option_value'], $data['option_created'], $data['option_edit'], $data['option_user']);
        $place_holders[] = "( %s, %s, %s, %s, %s)";
    }

    do_insert( $place_holders, $values );
}

Я придумал это решение, которое расширяет класс wpdb, чтобы он использовал его внутренние функции обработки данных:

<?php
class wpdbx extends wpdb {
  public function __construct() {
    parent::__construct(DB_USER, DB_PASSWORD, DB_NAME, DB_HOST);
  }

  public function insert_multiple($table, $data, $format = null) {
    $this->insert_id = 0;

    $formats = array();
    $values = array();

    foreach ($data as $index => $row) {
      $row = $this->process_fields($table, $row, $format);
      $row_formats = array();

      if ($row === false || array_keys($data[$index]) !== array_keys($data[0])) {
        continue;
      }

      foreach($row as $col => $value) {
        if (is_null($value['value'])) {
          $row_formats[] = 'NULL';
        } else {
          $row_formats[] = $value['format'];
        }

        $values[] = $value['value'];
      }

      $formats[] = '(' . implode(', ', $row_formats) . ')';
    }

    $fields="`" . implode('`, `', array_keys($data[0])) . '`';
    $formats = implode(', ', $formats);
    $sql = "INSERT INTO `$table` ($fields) VALUES $formats";

    $this->check_current_query = false;
    return $this->query($this->prepare($sql, $values));
  }
}

global $wpdbx;
$wpdbx = new wpdbx();
?>

Вы можете использовать это так:

<?php
global $wpdbx;
$results = $wpdbx->insert_multiple(
  'settings-table',
  array(
    array(
      'option_name'   => 'name-1', 
      'option_value'  => 'val-1', 
      'option_created'=> current_time('mysql'),
      'option_edit'   => current_time('mysql'),
      'option_user'   => 'user-1' 
    ),
    array(
      'option_name'   => 'name-2', 
      'option_value'  => 'val-2', 
      'option_created'=> current_time('mysql'),
      'option_edit'   => current_time('mysql'),
      'option_user'   => 'user-2' 
    ),
    array(
      'option_name'   => 'name-1', 
      'option_value'  => 'val-3', 
      'option_created'=> current_time('mysql'),
      'option_edit'   => current_time('mysql'),
      'option_user'   => 'user-3'
    )
  )
);
?>

Это также будет работать

        $nameArray = array("name-1", "name-2", "name-3");
        $valueArray = array("val-1", "val-2" , "val-3");
        $userArray = array("user-1" , "user-2", "user-3");
        $maxRow= count($nameArray); // может использовать количество любого массива
        $setting_values = array();
        $time = current_time('mysql');

        for($x=0;$x<$maxRow; $x++){
            $SettingContext = [
                'option_name' => "'" . $nameArray[$x] . "'",
                'option_value' => "'" . $valueArray[$x] . "'",
                'option_created' => "'" . $time . "'",
                'option_edit' => "'" . $time . "'",
                'option_user' => "'" . $userArray[$x] . "'"
            ];
            $setting_values[] = "(" . implode(',', $SettingContext) . ")";
        }
        $settingSubmit = implode(',', $setting_values);
        $setting_save = $wpdb->query("
                INSERT INTO setting
                (option_name, option_value, option_created,option_edit, option_user)
                VALUES " . $settingSubmit
        );

Человек, у которого я задавал вопрос, был Кришнил Сингх, так что мой @комментарий теперь не на том месте

Ответ или решение

Для вставки нескольких записей в таблицу базы данных WordPress с использованием класса wpdb, есть несколько подходов, которые позволяют значительно упростить процесс и повысить производительность по сравнению с выполнением многочисленных отдельных запросов. В данной статье мы рассмотрим преимущества и недостатки различных методов, а также предложим некоторые примеры кода.

1. Использование метода wpdb->insert

Метод wpdb->insert предназначен для вставки одной записи за раз. Вот как его можно использовать для вставки нескольких записей:

global $wpdb;

$data = [
    ['option_name' => 'name-1', 'option_value' => 'val-1', 'option_created' => current_time('mysql'), 'option_edit' => current_time('mysql'), 'option_user' => 'user-1'],
    ['option_name' => 'name-2', 'option_value' => 'val-2', 'option_created' => current_time('mysql'), 'option_edit' => current_time('mysql'), 'option_user' => 'user-2'],
    ['option_name' => 'name-3', 'option_value' => 'val-3', 'option_created' => current_time('mysql'), 'option_edit' => current_time('mysql'), 'option_user' => 'user-3'],
];

foreach ($data as $row) {
    $wpdb->insert('settings-table', $row);
}

Этот подход работает, но как видно, нам нужно будет циклом вставлять каждую запись отдельно, что может быть низкоэффективно при большом объеме данных.

2. Использование одного SQL-запроса для вставки множественных записей

Вместо многократного вызова wpdb->insert, можно использовать один запрос для вставки всех записей сразу:

global $wpdb;

$values = [];
$placeholders = [];
foreach ($data as $row) {
    $placeholders[] = '( %s, %s, %s, %s, %s )';
    $values[] = $row['option_name'];
    $values[] = $row['option_value'];
    $values[] = current_time('mysql');
    $values[] = current_time('mysql');
    $values[] = $row['option_user'];
}

$query = "INSERT INTO `settings-table` (`option_name`, `option_value`, `option_created`, `option_edit`, `option_user`) VALUES " . implode(', ', $placeholders);
$wpdb->query($wpdb->prepare($query, $values));

Этот подход значительно сокращает количество запросов и повышает эффективность, особенно если объем данных велик.

3. Расширение класса wpdb

Можно создать собственный метод в классе wpdb, который позволит осуществлять массовую вставку:

class wpdbx extends wpdb {
    public function insert_multiple($table, $data) {
        $formats = [];
        $values = [];

        foreach ($data as $row) {
            if (array_keys($row) !== array_keys($data[0])) {
                continue; // Убедитесь, что все записи имеют одинаковую структуру
            }

            $values[] = implode(', ', array_map(function($col) { return '%s'; }, array_values($row)));
            $formats[] = sprintf("(%s)", implode(', ', $values));
        }

        $columns = implode(', ', array_keys($data[0]));
        $sql = "INSERT INTO `$table` ($columns) VALUES " . implode(', ', $formats);

        return $this->query($this->prepare($sql, $values));
    }
}

// Использование нового метода
global $wpdbx;
$wpdbx = new wpdbx();
$results = $wpdbx->insert_multiple('settings-table', $data);

Заключение

Использование метода wpdb->insert для каждой записи может быть утомительным и неэффективным, особенно при обработке большого объема данных. В большинстве случаев рекомендуется использовать один SQL-запрос для вставки всех записей, что значительно сокращает количество запросов к базе данных. Если вы хотите упростить процесс и повысить эффективность, стоит рассмотреть вариант расширения класса wpdb, добавляя удобные методы для массовой вставки.

Эти техники не только упрощают процесс работы с базой данных, но и позволяют поддерживать код чистым и оптимизированным. Надеюсь, эти рекомендации окажутся полезными для вашего проекта!

Оцените материал
Добавить комментарий

Капча загружается...