$wpdb no inserta NULL en la columna de la tabla

5 may 2014, 16:01:47
Vistas: 17K
Votos: 15

Cuando intento algo como esto:

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

En la columna status ahora tengo una cadena vacía '', simplemente no la establece como NULL.

La columna puede ser NULL por supuesto. También he probado con $wpdb->query y $wpdb->prepare y los resultados son los mismos. ¿Estoy haciendo algo mal?

0
Todas las respuestas a la pregunta 3
1
12

Actualización:

Desde WordPress 4.4, esto ahora es compatible con los métodos insert, update, replace y delete de wpdb y el ticket #15158 ha sido cerrado como corregido.

Gracias a @dmsnell por comentar sobre esa actualización.

Por otro lado, el soporte para null en wpdb::prepare() actualmente está cerrado como no corregido en el ticket #12819.

Respuesta anterior:

NULL no soportado:

Parece que tendrás que escribir tu propio SQL personalizado para actualizar el valor con NULL.

Actualmente NULL no es soportado por $wpdb->prepare(), que toma la entrada a través de la función de formato vsprintf.

Revisa estos tickets abiertos en Trac:

Estos tickets tienen unos 4 años, así que no esperaría que esto sea soportado en el núcleo pronto ;-)

Deberías echar un vistazo al código fuente como sugirió @s_ha_dum.

Una posible solución:

Si te sientes aventurero, puedes probar lo siguiente con el filtro query:

    // Añadir un filtro para reemplazar la cadena 'NULL' con NULL
    add_filter( 'query', 'wpse_143405_query' );

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

    // Eliminar el filtro nuevamente:
    remove_filter( 'query', 'wpse_143405_query' );

donde

/**
 * Reemplaza la cadena 'NULL' con NULL
 * 
 * @param  string $query
 * @return string $query
 */

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

Quizás quieras usar una cadena más única que 'NULL' para reemplazar, tal vez '###NULL###' en su lugar.

5 may 2014 17:48:19
Comentarios

el soporte para establecer NULL fue añadido en r34737, por lo que ya no es necesario ningún método alternativo

dmsnell dmsnell
12 jul 2016 01:47:19
0

wpdb->update utiliza por defecto cadenas de texto para todos los tipos de datos.

format
(array|string) (opcional) Un array de formatos que se asignarán a cada valor en $data. Si es una cadena, ese formato se usará para todos los valores en $data. Si se omite, todos los valores en $data se tratarán como cadenas a menos que se especifique lo contrario en wpdb::$field_types.

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

Puedes especificar un formato pero los especificadores permitidos son:

Valores de formato posibles: %s como cadena; %d como entero (número entero) y %f como float. (Ver más abajo para más información.) Si se omite, todos los valores en $where se tratarán como cadenas.

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

Puedes leer el código fuente y entender el proceso.

Si modificas el método wpdb->prepare (en un servidor de desarrollo que se borra periódicamente :) ) para volcar el SQL justo antes del return, verás que el reemplazo ocurre antes de wpdb->prepare:

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

Aunque, como sugiere @birgire, bien podría ser una limitación de prepare lo que provocó ese reemplazo.

5 may 2014 17:48:54
0

Me gustaría explicar con más detalle cómo hacer esto en WP 4.4 y versiones posteriores. Necesitas establecer tanto el elemento de datos como el de formato que deseas que sean nulos a un valor 'null' de PHP.

El ejemplo en el ticket #15158 es el siguiente:

$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'
            ]);
26 nov 2017 21:23:52