$ wpdb не будет вставлять NULL в столбец таблицы


13

Когда я пытаюсь что-то вроде этого

    $status = NULL;

    $wpdb->update(
            'table',
            array( 
                'status' => $status,
            ), 
            array( 'id' => 1 ) 
    );

В столбце «status» теперь у меня есть пустая строка '', она просто не будет иметь значение NULL.

Конечно, столбец может быть пустым. Я также протестировал $ wpdb-> query и $ wpdb-> prepare, и результаты совпадают. Я делаю что-то неправильно?

Ответы:


9

Обновить:

Начиная с WordPress 4.4. это теперь поддерживается insert, update, replaceи deleteметоды wpdbи билет # 15158 был закрыт , как фиксированный .

Спасибо @dmsnell за комментарии об этом обновлении.

С другой стороны, nullподдержка в wpdb::prepare()настоящее время закрыта как wontfix в тикете # 12819 .

Предыдущий ответ:

NULL не поддерживается:

Похоже, вам придется написать свой собственный SQL, чтобы обновить значение NULL.

В настоящее время NULLне поддерживается тем $wpdb->prepare(), что принимает ввод через функцию форматирования vsprintf .

Проверьте эти открытые билеты Trac:

Этим билетам около 4 лет, так что я не задерживаю дыхание, пока это не будет поддержано ядром ;-)

Вы должны взглянуть на источник, как предложено @s_ha_dum.

Возможный обходной путь:

Если вы любите приключения, вы можете попробовать следующее с queryфильтром:

    // Add a filter to replace the 'NULL' string with NULL
    add_filter( 'query', 'wpse_143405_query' );

    global $wpdb;
    $wpdb->update(
        'table',
        array( 
            'status' => 'NULL',
        ), 
        array( 'id' => 1 ) 
    );

    // Remove the filter again:
    remove_filter( 'query', 'wpse_143405_query' );

где

/**
 * Replace the 'NULL' string with NULL
 * 
 * @param  string $query
 * @return string $query
 */

function wpse_143405_query( $query )
{
    return str_ireplace( "'NULL'", "NULL", $query ); 
}

Возможно, вы захотите использовать более уникальную строку, чем 'NULL'заменить, возможно, '###NULL###'вместо этого.


2
поддержка настроек NULLбыла добавлена ​​в r34737 , так что больше нет необходимости в
обходном

3

wpdb->update по умолчанию используется строка для всех типов данных.

format
(array | string) (необязательно) Массив форматов, которые должны быть сопоставлены каждому значению в $ data. Если строка, этот формат будет использоваться для всех значений в $ data. Если опущено, все значения в $ data будут обрабатываться как строки, если иное не указано в wpdb::$field_types.

http://codex.wordpress.org/Class_Reference/wpdb#UPDATE_rows

Вы можете указать формат, но допустимыми спецификаторами являются:

Возможные значения формата :% s в виде строки; % d как целое число (целое число) и% f как число с плавающей точкой. (См. Ниже для получения дополнительной информации.) Если пропущено, все значения в $, где будут рассматриваться как строки.

http://codex.wordpress.org/Class_Reference/wpdb#UPDATE_rows

Вы можете прочитать источник и отработать процесс.

Если вы взломаете wpdb->prepareметод (на сервере dev, который периодически очищается :)), чтобы выгружать SQL перед передачей, вы увидите, что замена происходит раньше wpdb->prepare:

string(48) "UPDATE `table` SET `status` = %s WHERE `id` = %s"

Хотя, как подсказывает @birgire, вполне возможно, что это побудит вас к prepareзамене.


2

Я хотел бы подробнее объяснить, как это сделать в WP 4.4 и более поздних версиях. Вам нужно установить как данные, так и элемент формата, который вы хотите иметь значение null, равным значению PHP 'null'.

Пример в билете № 15158 выглядит следующим образом:

$wpdb->update($ttable, 
              [
                'user_id' => NULL,
                'status' => 'available',
                'update_time' => $now->format('Y-m-d H:i:s')
              ], [
                'therapist_id' => $therapist_id,
                'user_id' => $user_id,
                'start_time' => $ub['start_time']
              ], [
                 NULL,
                 '%s',
                 '%s'
              ], [
                 '%d',
                 '%d',
                 '%s'
            ]);
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.