Обновление нескольких строк в $wpdb с помощью IN, как в обычном SQL

1 авг. 2014 г., 17:08:52
Просмотры: 15.3K
Голосов: 7

Мне интересно, возможно ли использовать $wpdb->update для обновления значений в нескольких строках с помощью условия IN, как в "обычном" SQL.

Я хочу реализовать что-то вроде этого примера:

UPDATE [table]
SET [column_1] = [updated_value]
WHERE [column_2] IN ([comma_separated_ids])

Я искал информацию о том, как это можно сделать, но пока не нашел ни одного вопроса или статьи, объясняющей, возможно ли это.

Пока я использую обычный запрос, но было бы удобнее иметь простое однострочное решение.

3
Комментарии

Нет причин, чтобы это не работало.

Mark Kaplun Mark Kaplun
1 авг. 2014 г. 17:18:14

Но КАК? Я пробовал добавить строку с разделителями-запятыми в качестве значения в массив where, но обновился только первый id.

Ludvig Sjöbeck Ludvig Sjöbeck
1 авг. 2014 г. 17:54:53

Хм, вижу, что люди с лучшими знаниями, чем у меня, уже ответили ;)

Mark Kaplun Mark Kaplun
1 авг. 2014 г. 18:41:20
Все ответы на вопрос 1
5
12

Как видно в исходном коде, знак = жестко прописан в методе wpdb::update(), поэтому по умолчанию нельзя использовать оператор IN в методе обновления.

Самый простой способ обойти это ограничение — использовать wpdb::query() с вашим SQL-запросом, но обязательно правильно экранируйте все значения.

Пример:

function wpdb_update_in( $table, $data, $where, $format = NULL, $where_format = NULL ) {

    global $wpdb;

    $table = esc_sql( $table );

    if( ! is_string( $table ) || ! isset( $wpdb->$table ) ) {
        return FALSE;
    }

    $i          = 0;
    $q          = "UPDATE " . $wpdb->$table . " SET ";
    $format     = array_values( (array) $format );
    $escaped    = array();

    foreach( (array) $data as $key => $value ) {
        $f         = isset( $format[$i] ) && in_array( $format[$i], array( '%s', '%d' ), TRUE ) ? $format[$i] : '%s';
        $escaped[] = esc_sql( $key ) . " = " . $wpdb->prepare( $f, $value );
        $i++;
    }

    $q         .= implode( $escaped, ', ' );
    $where      = (array) $where;
    $where_keys = array_keys( $where );
    $where_val  = (array) array_shift( $where );
    $q         .= " WHERE " . esc_sql( array_shift( $where_keys ) ) . ' IN (';

    if( ! in_array( $where_format, array('%s', '%d'), TRUE ) ) {
        $where_format = '%s';
    }

    $escaped = array();

    foreach( $where_val as $val ) {
        $escaped[] = $wpdb->prepare( $where_format, $val );
    }

    $q .= implode( $escaped, ', ' ) . ')';

    return $wpdb->query( $q );
}

Затем используйте функцию следующим образом:

wpdb_update_in(
  'posts', // таблица
  array( 'post_author' => '1', 'post_status' => 'draft' ), // данные
  array( 'post_author' => array( '2', '3', '4', '5' ) ), // условие
  array( '%d', '%s' ), // формат
  '%d' // формат условия
);

Выполненный SQL-запрос будет выглядеть так:

UPDATE wp_posts
SET post_author = 1, post_status = 'draft'
WHERE post_author IN (2, 3, 4, 5)
1 авг. 2014 г. 18:29:41
Комментарии

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

Ludvig Sjöbeck Ludvig Sjöbeck
4 авг. 2014 г. 10:13:36

Жестко закодировано в WordPress и сложно в использовании...

Vishal Kumar Sahu Vishal Kumar Sahu
11 сент. 2017 г. 01:00:12

Я нашел это полезным, но похоже, что некоторые вещи изменились с момента написания этого ответа. Во-первых, сигнатура функции implode() поменяла порядок параметров начиная с PHP 7.4. Также я не смог понять, что такое $wpdb->$table? В итоге убрал это.

JDandChips JDandChips
16 июн. 2021 г. 17:21:28

также есть формат %f для авторизации

ZalemCitizen ZalemCitizen
21 апр. 2024 г. 00:55:24

За 10 лет многое изменилось, да :)

$wpdb->$table — это способ получить полное имя таблицы. Вам не следует использовать, например, "wp_content", а лучше $wpdb->content, потому что префикс может измениться, а в мультисайте он обязательно изменится.

Это не изменилось. Но теперь у нас есть заполнитель %i для экранирования имён таблиц.

Что касается %f, да, он был добавлен относительно недавно вместе с упомянутым выше %i.

gmazzap gmazzap
2 мая 2024 г. 21:03:10