$wpdb->get_results(...) devuelve un array vacío a pesar de una consulta correcta
Como indica el título, no puedo hacer que $wpdb->get_results devuelva resultados. Ejecutar la consulta "cruda" tiene éxito, pero esto parece fallar por alguna extraña razón desconocida.
global $wpdb;
$sql = "SELECT *
FROM something aki,
somethingelse akb,
somethingelseelse ac
WHERE aki.keyID = akb.keyID
AND akb.someID = ac.someID
AND aki.type LIKE '%thing%'";
$corps = $wpdb->get_results($sql, OBJECT);
var_dump($corps);
Usa $wpdb->show_errors( true )
antes de la consulta y mira qué error devuelve.
Mi problema (porque he experimentado lo mismo) fue que debería usar $wpdb->posts
en lugar de wp_posts
dentro de la consulta. El prefijo de las tablas puede cambiar de una instalación de WP a otra o incluso en la misma instalación dependiendo del momento (por ejemplo, un administrador puede cambiar el prefijo cuando quiera). Por lo tanto, se debería escribir la consulta así:
$query = "select <stuff here> from $wpdb->posts where <stuff here>";

Estaba solucionando un problema con mi script que producía un array vacío en WordPress con una cadena MySQL aparentemente correcta. Resultó que, a diferencia de la persona que hizo la pregunta, yo usé $wpdb->prepare(), pero la solución que encontré puede ser útil para alguien que encuentre esta pregunta y respuesta (como me pasó a mí).
Esta cadena, AND aki.type LIKE '%thing%'"
, contiene comodines de porcentaje (%
) que indican que estamos buscando una celda aki.type
que contenga thing
como parte de su valor.
$wpdb->prepare
los convierte en hashes, y el servidor MySQL recibe algo como esto: AND aki.type LIKE '{399038939300d2c307c53b29a166ee90101da7b2aba7978a898694010bf1bfe6}thing{399038939300d2c307c53b29a166ee90101da7b2aba7978a898694010bf1bfe6}'
. ¡Naturalmente, no se obtendrían resultados!
La página de wpdb::prepare dice: 'Los signos de porcentaje literales (%) en la cadena de consulta deben escribirse como %%. Los comodines de porcentaje (por ejemplo, para usar en sintaxis LIKE) deben pasarse a través de un argumento de sustitución que contenga la cadena LIKE completa, estos no se pueden insertar directamente en la cadena de consulta. Ver también wpdb::esc_like().'
Por lo tanto, la parte LIKE
debe prepararse así (ejemplo de la página de wpdb::esc_like()):
$wild = '%';
$find = 'only 43% of planets';
$like = $wild . $wpdb->esc_like( $find ) . $wild;
$sql = $wpdb->prepare( "SELECT * FROM $wpdb->posts WHERE post_content LIKE %s", $like );
Donde $wpdb->esc_like()
debe usarse antes de $wpdb->prepare()
.
Y si alguien quiere reemplazar manualmente los marcadores de posición de comodines de porcentaje, debe usar $wpdb->remove_placeholder_escape() después de $wpdb->prepare()
.

Publico esto aquí porque la consulta en la pregunta es muy similar a lo que yo tenía, aunque no era obvio inmediatamente que en mi caso el problema estaba en $wpdb->prepare()
. Creo que alguien más podría llegar a esta página con el mismo problema.

Tu problema es algo similar, pero no igual a la pregunta original. Sugiero abrir una nueva pregunta y luego responderla (responder tu propia pregunta está bien visto). Entonces puedes marcar tu respuesta como la aceptada, y las personas que tengan problemas con $wpdb->prepare()
(en vez de $wpdb->get_results()
) podrán encontrar más fácilmente tu pregunta y respuesta.

Entendido Pat J. ¿Crees que debería dejar esta respuesta aquí o borrarla?

Yo diría que lo dejes. Si un administrador considera que es inapropiado, puede eliminarlo.

hecho https://wordpress.stackexchange.com/q/406772/190417

Puede que sea un poco tarde, pero te falta la llamada "prepare" necesaria en WordPress:
$Table_Name = $wpdb->prefix.'Nombre de tu tabla';
$sql_query = $wpdb->prepare("SELECT * FROM $Table_Name WHERE aki.keyID=%d AND akb.someID=%d AND aki.type like %s", akb.keyID, ac.someID, ''%thing%');
$result = $wpdb->query( $sql_query );
Múltiples resultados pueden encontrarse en el array.

Mencionó que tenía el nombre de la tabla incorrecto arriba. La llamada a $wpdb->prepare() no es necesaria para una consulta que es completamente estática y no proviene del usuario, por lo que no es probable que sea útil aquí. En cualquier caso, tu línea prepare() anterior contiene código que no es PHP.

Para búsquedas numéricas no... pero para búsquedas de cadenas en mySQL, requieren un conjunto diferente de paso de parámetros que la llamada prepare hace por ti. De lo contrario, tienes que insertar el '%s%' alrededor de la cadena. Si no lo haces, la búsqueda en mysql falla.

Correcto, pero lo leíste mal. "Estático" significa que no cambia, es decir, una consulta basada completamente en texto fijo, con variables insertadas. La consulta mostrada era texto fijo (también conocido como "estático") así que usar prepare no añade nada. Sin embargo, es una buena práctica usar prepare() cuando interpolas valores en una consulta (también conocido como dinámico o no estático). Saludos.

Tuve el mismo problema, una sentencia SQL correcta, sin errores, pero sin resultados al usar wpdb.
La solución para mí fue tener la codificación/cotejamiento de caracteres correcto (por ejemplo COLLATE 'utf8_general_ci') para mi tabla.
Tenía una consulta que funcionaba, la tabla fue reemplazada con un volcado de otro servidor (un servidor más antiguo) y mi consulta dejó de funcionar. Retornaba NULL o 0 aunque al ejecutar la consulta directamente en la base de datos devolvía los resultados correctos.
Creé las tablas de ambas formas (varias veces porque no lo podía creer), ejecuté el mismo script de inserción de datos y no cambié mi código PHP/wpdb.
Cuando la tabla se creó con esto, mi consulta NO funcionó:
CREATE TABLE IF NOT EXISTS `vf_user` (
`id` mediumint(9) NOT NULL AUTO_INCREMENT,
`email` varchar(50) NOT NULL,
`full_name` varchar(25) NOT NULL,
`password` varchar(25) NOT NULL,
`role` enum('user','tester','admin') NOT NULL DEFAULT 'user',
`phone` varchar(25) NOT NULL,
`last_modified` timestamp NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp(),
`user_activation_key` varchar(100) DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE,
UNIQUE KEY `email` (`email`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=325 DEFAULT CHARSET=utf8 COMMENT='users table';
Cuando se creó con esto, mi consulta SI devolvió resultados:
CREATE TABLE `vf_user` (
`id` MEDIUMINT(9) NOT NULL AUTO_INCREMENT,
`email` VARCHAR(50) NOT NULL COLLATE 'utf8_general_ci',
`full_name` VARCHAR(25) NOT NULL COLLATE 'utf8_general_ci',
`password` VARCHAR(25) NOT NULL COLLATE 'utf8_general_ci',
`role` ENUM('user','tester','admin') NOT NULL DEFAULT 'user' COLLATE 'utf8_general_ci',
`phone` VARCHAR(25) NOT NULL COLLATE 'utf8_general_ci',
`last_modified` TIMESTAMP NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp(),
`user_activation_key` VARCHAR(100) NULL DEFAULT NULL COLLATE 'utf8_general_ci',
PRIMARY KEY (`id`) USING BTREE,
UNIQUE INDEX `email` (`email`) USING BTREE
)
COMMENT='users with access to the virtual festival'
COLLATE='utf8_general_ci'
ENGINE=InnoDB
AUTO_INCREMENT=325
;

La función wpdb->get_results de WordPress devuelve el resultado si es exitoso, de lo contrario devolverá null. Puede haber muchas razones por las que una consulta falle. Consulta el artículo detallado sobre depuración get_results() devolviendo resultados vacíos aquí.
Aunque puedes usar funciones como wpdb->show_error()
para ver cuál fue el último error después de ejecutar la consulta SQL. A veces este error devuelve vacío, entonces intenta usar wpdb->last_query
para verificar la consulta final que se formó.
