$wpdb->last_error no muestra la consulta en caso de error
Estoy insertando datos en una tabla personalizada usando $wpdb->insert
. Sin embargo, al ocurrir un error, no obtengo información de $wpdb->last_error
. ¿Cuál podría ser la causa?
Ya tengo esta configuración en wp-config
:
define('WP_DEBUG', false);
define('SAVEQUERIES', true);
El código es el siguiente:
$result = $wpdb->insert($this->table, $data_);
if (false === $result) {
error_log($wpdb->last_error);
}
$this->table
y $data_
están poblados correctamente ya que la operación se ejecuta con éxito. Pero no obtengo información sobre la consulta que falló. ¿Hay alguna forma de obtener la consulta real ejecutada en $wpdb->insert
?
Solución
Resolví el problema. La consulta de inserción fallaba porque uno de los datos de columna era demasiado grande y excedía el tamaño de la columna en la base de datos. La columna era varchar(500)
pero los datos reales superaban los 500 caracteres, lo que causaba el fallo. Cambié la columna a TEXT
y la inserción se completó sin errores.
Si quieres la consulta, será $wpdb->last_query
(ten en cuenta que tampoco necesitas SAVEQUERIES
, eso es solo si quieres un registro de todas las consultas ($wpdb->queries
).
last_error
es... bueno, ¡el error!
Actualización: Posible explicación de que last_error
esté vacío - este es el código fuente de wpdb::query()
:
// Si estamos escribiendo en la base de datos, asegurémonos de que la consulta se escriba de forma segura.
if ( $this->check_current_query && ! $this->check_ascii( $query ) ) {
$stripped_query = $this->strip_invalid_text_from_query( $query );
// strip_invalid_text_from_query() puede realizar consultas, así que necesitamos
// hacer flush nuevamente, solo para asegurarnos de que todo esté limpio.
$this->flush();
if ( $stripped_query !== $query ) {
$this->insert_id = 0;
return false;
}
}
// Código omitido
// Mantener un registro de la última consulta para depuración...
$this->last_query = $query;
$this->_do_query( $query );
// Código omitido
// Si hay un error, tomar nota de él...
if ( $this->use_mysqli ) {
$this->last_error = mysqli_error( $this->dbh );
} else {
$this->last_error = mysql_error( $this->dbh );
}
En otras palabras, WordPress parece verificar previamente la consulta y abortará si considera que fallará - en este caso obtienes tu return false
pero no se establecerá ningún error (ya que nunca se envió al servidor MySQL).

pero ¿por qué sigo sin obtener nada en last_error? la consulta de inserción devuelve false lo que significa que algo falló, pero aún así no hay nada en last_error? ¿Extraño?

https://core.trac.wordpress.org/ticket/32315
Uno de los campos de entrada puede ser más grande de lo que permite la columna. WordPress detecta esto y ni siquiera enviará la consulta a la base de datos.
El Diff muestra un parche para wp-db que puedes aplicar para obtener más información en el mensaje de last_error, evitando que quede vacío.

Esta es realmente una respuesta genial. He adaptado tu respuesta en un archivo wp-content/db.php para que pueda ser fácil y rápidamente implementado como solución persistente entre actualizaciones de WordPress. Ver aquí para el gist y más detalles.

¡Oh, genial, gracias @BrianC! Hace un rato vi un correo diciendo que este problema tiene un hito para la versión 5.6 ahora.
