Вопрос или проблема
Так что после того, как я создал таблицу ‘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
, добавляя удобные методы для массовой вставки.
Эти техники не только упрощают процесс работы с базой данных, но и позволяют поддерживать код чистым и оптимизированным. Надеюсь, эти рекомендации окажутся полезными для вашего проекта!