WPDB вставка или обновление, если существует

20 мая 2014 г., 23:14:22
Просмотры: 76.2K
Голосов: 32

Я не слишком хорошо знаком с WPDB или SQL в целом, но у меня есть пользовательская таблица для моего проекта, и я пытаюсь присвоить ей некоторые метаданные. Что бы я "хотел", чтобы произошло: если строка существует - обновить её, если нет - вставить новую. Я прочитал про Insert и Update в документации WPDB, но ни один из них не рассматривал ситуацию "либо то, либо другое". Я думал, что смогу работать с update, поэтому мой код пока выглядит так:

// Обновление записи в таблице
$wpdb->update(
    $wpdb->prepare(
        $wpdb->prefix.'item_info',
        array(
            'post_id'       => $post_id,
            'item_stock'    => $item_stock
        ),
        array('post_id' => $post_id)
    )
);

Есть ли в WordPress что-то вроде "ЕСЛИ существует - обновить, ИНАЧЕ - вставить", или мне нужно выполнять пользовательский SQL-запрос для достижения этого, или мне нужно сначала сделать запрос к базе данных, чтобы проверить, существует ли ID в моей таблице, а ЗАТЕМ решить, обновлять его или вставлять?

0
Все ответы на вопрос 5
6
37

Вы пробовали использовать $wpdb->replace? Согласно WP Codex:

Заменяет строку в таблице, если она существует, или вставляет новую строку, если такой строки еще нет.

Я сам использовал этот метод в нескольких плагинах, и он отлично справляется с предотвращением ошибок дублирования уникальных ID и подобных проблем.

Подробнее в кодексе

5 сент. 2014 г. 02:39:12
Комментарии

Это сработало для меня, в то время как пользовательский запрос не сработал — спасибо за упоминание replace()

trainoasis trainoasis
25 янв. 2016 г. 10:49:02

Это правильный ответ на вопрос.

Tyler Jones Tyler Jones
20 сент. 2016 г. 12:19:55

стоит отметить, что $wpdb->replace полностью перезаписывает всю запись, тогда как $wpdb->update обновляет только указанные поля из массива $data

MatthewLee MatthewLee
9 дек. 2016 г. 06:46:55

Эта функция сейчас не выполняет замену для меня. Она дублирует одни и те же строки. Может ли PRIMARY KEY (id) быть причиной, которая препятствует замене? Я не могу найти информацию об этом в Codex.

Viktor Borítás Viktor Borítás
14 мая 2020 г. 19:54:46

Я разобрался: чтобы избежать проблемы с заменой, также необходимо применить ограничение UNIQUE к определенным столбцам при создании таблицы, что делает возможным создание уникальных строк.

Viktor Borítás Viktor Borítás
14 мая 2020 г. 20:12:02

@ViktorBorítás - или, скорее, делает невозможным создание дублирующихся строк?

Kropotkin Kropotkin
29 июн. 2023 г. 13:53:54
Показать остальные 1 комментариев
3
32

Во-первых, вы используете prepare неправильно. Похоже, что вы обернули аргументы $wpdb->update в $wpdb->prepare таким образом. Это не сработает. Фактически, вы передаёте в update только один аргумент — результат выполнения prepare. Попробуйте что-то простое, например, следующее, и вы поймёте, почему это не работает:

$post_id = 123;
$item_stock = 567;
var_dump(
  $wpdb->prepare(
    $wpdb->prefix.'item_info',
    array(
        'post_id'       => $post_id,
        'item_stock'    => $item_stock
    ),
    array('post_id' => $post_id)
  )
);

Кроме того, $wpdb->update() сам выполняет prepare за вас.

Во-вторых, если бы это был я, я бы избегал излишней сложности с вспомогательными функциями и написал бы правильный запрос ON DUPLICATE KEY UPDATE:

$sql = "INSERT INTO {$wpdb->prefix}item_info (post_id,item_stock) VALUES (%d,%s) ON DUPLICATE KEY UPDATE item_stock = %s";
// var_dump($sql); // отладка
$sql = $wpdb->prepare($sql,$post_id,$item_stock,$item_stock);
// var_dump($sql); // отладка
$wpdb->query($sql);

Это предполагает, что post_id является UNIQUE индексом или PRIMARY KEY. Если структура вашей таблицы соответствует моим предположениям, позвольте базе данных разобраться с этим.

21 мая 2014 г. 16:09:45
Комментарии

Это было невероятно полезно... Спасибо за уделенное время, s_ha_dum!

Jake Jake
30 июл. 2014 г. 18:01:56

Метод prepare возвращает false для меня - других ошибок БД нет. Если выполнить запрос вручную через phpmyadmin, все работает как ожидалось. Также проверил, что переменные содержат правильные значения.. Есть идеи?

trainoasis trainoasis
25 янв. 2016 г. 10:37:27

Что делать, если post_id не является PRIMARY KEY?

Mike Kormendy Mike Kormendy
29 нояб. 2016 г. 02:36:02
1

Вы можете попробовать обновить таблицу с помощью $wpdb->update. В следующем коде я использую id, но вы можете использовать любые критерии.

$result = $wpdb->update($tableName, $info, array('id' => $info["id"]));
// Если не найдено записей для обновления, попытается создать запись.
if ($result === FALSE || $result < 1) {
    $wpdb->insert($tableName, $info);
}

Результат работы Update()

  • $result === FALSE : Ошибка
  • $result === 0 : Успешно, но ничего не обновлено
  • $result > 1: Успешно и обновлено
17 июн. 2021 г. 21:18:40
Комментарии

Если значения одинаковы, MySQL не будет обновлять строку, поэтому количество затронутых строк будет равно 0.

Darrel K. Darrel K.
8 окт. 2021 г. 09:28:48
1
-1

Сначала следует проверить, существует ли строка.

Скорее всего, вам нужно сначала получить ID или первичный ключ строки, которую вы пытаетесь обновить. Затем использовать $wpdb->update, если строка существует, или $wpdb->insert, если её нет.

20 мая 2014 г. 23:40:08
Комментарии

Пример того, как проверить существование ID или первичного ключа, сделал бы этот ответ по-настоящему полезным. Сейчас это почти как повторение вопроса.

Jake Jake
30 июл. 2014 г. 17:57:12
1
-1

используйте $wpdb->insert, $wpdb->insert может также вставлять и обновлять.. В 2023

РЕДАКТИРОВАТЬ $wpdb->insert не обновляет строку, используйте $wpdb->replace

20 нояб. 2023 г. 14:20:25
Комментарии

Важно отметить различие: wpdb::replace() действительно удаляет, а затем вставляет запись при обнаружении дубликата — он не выполняет wpdb::update(), что необходимо учитывать в каждом конкретном случае использования.

Howdy_McGee Howdy_McGee
20 нояб. 2023 г. 21:29:54