$wpdb no inserta NULL en la columna de la tabla
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?

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.

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

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 enwpdb::$field_types
.
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.
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.

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'
]);
