$wpdb->get_results(...) devuelve un array vacío a pesar de una consulta correcta

22 sept 2014, 08:14:28
Vistas: 18K
Votos: 9

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);
9
Comentarios

¿Has intentado ejecutar esta consulta directamente en phpmyadmin?

TBI Infotech TBI Infotech
22 sept 2014 08:15:31

Sí, tanto en phpmyadmin como directamente en la terminal de mysql. Funciona en ambos. Sin embargo, no obtengo resultados (array vacío) en $wpdb->get_results

1Up 1Up
22 sept 2014 08:40:15

No logro identificar el problema exacto. Pero puedes depurarlo usándolo sin el segundo parámetro OBJECT y utilizando una consulta simple, luego agregando condiciones. Así podrás identificar el problema

TBI Infotech TBI Infotech
22 sept 2014 08:49:04

Complementando el comentario de @TBIInfotech, ¿estás recordando usar el prefijo WP en tus tablas cuando sea relevante?

Joshua Joshua
22 sept 2014 09:25:09

Arrrr... Acabo de usar $wpdb->show_errors( true ) antes de la consulta y obtuve el error. Parece que WP comenzó a codificar el carácter ' dentro de las consultas de repente y sin motivo aparente... Podría ser la razón de tus problemas también. Quizás quieras pasar '%thing%' como parámetro a get_reults.

NoOne NoOne
27 feb 2016 21:44:42

Finalmente, mi problema resultó ser que debería usar $wpdb->posts en lugar de wp_posts dentro de la consulta. Supongo que, por alguna razón, sin motivo aparente, las tablas de la base de datos en nuestro servidor fueron renombradas? WTF?!?!?!

NoOne NoOne
27 feb 2016 22:03:10

@NoOne Si lo resolviste, por favor publica una respuesta y acéptala :) (esto evitará que la pregunta aparezca en nuestra lista de no respondidas). Siempre debes usar el prefijo establecido en lugar de confiar en que siempre será wp_

Tim Malone Tim Malone
28 jun 2016 01:42:03

@TimMalone No es mi pregunta, así que no puedo aceptarla. Pero publicaré una respuesta. Eso podría ayudar a algunas personas... ;)

NoOne NoOne
30 jun 2016 19:35:10

@NoOne Ja ja, muy cierto. ¡Gracias por publicar una respuesta! Estoy intentando gestionar la lista de preguntas no respondidas en este momento ;)

Tim Malone Tim Malone
30 jun 2016 22:24:00
Mostrar los 4 comentarios restantes
Todas las respuestas a la pregunta 5
0

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>";
27 feb 2016 21:46:48
5

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().

14 jun 2022 10:18:21
Comentarios

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.

Artem Artem
14 jun 2022 10:24:40

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.

Pat J Pat J
14 jun 2022 18:08:12

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

Artem Artem
14 jun 2022 18:55:22

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

Pat J Pat J
14 jun 2022 20:44:50
3

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.

6 mar 2019 01:27:14
Comentarios

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.

Brian C Brian C
11 abr 2020 07:31:20

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.

Debbie Kurth Debbie Kurth
13 abr 2020 00:49:30

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.

Brian C Brian C
13 abr 2020 10:04:04
0

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
;
25 nov 2020 12:05:48
0

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ó.

6 ago 2021 20:24:08