Soporte » WordPress Avanzado » Consulta SQL

  • Resuelto pablocianes

    (@pablocianes)


    Hola, estoy intentando probar una consulta con $wpdb y en el WHERE quiero introducir varios valores procedentes de un array y me funciona pero no obtengo mas que el correspondiente al primer valor del array (para el ID 534 según el ejemplo), y no entiendo el motivo. ;-(

    La consulta es:

    $id_plugins = implode(',',array(534,536,538,540));  
    global $wpdb;
    $sql_query =
    "SELECT p.post_title AS titulo, p.post_content AS contenido, 
    pm.meta_key, pm.meta_value
    FROM {$wpdb->posts} AS p
    INNER JOIN {$wpdb->postmeta} AS pm ON (p.ID = pm.post_id)
    WHERE p.post_status = 'publish' AND p.post_type = %s AND pm.post_id IN (%d) AND pm.meta_key LIKE %s ;";
    
    $sql_query = $wpdb->prepare( $sql_query, 'plugins' , $id_plugins , '_url_plugin_%' );
    $results = $wpdb->get_results( $sql_query );
    if ( ! $results || ! is_array( $results ) ) {
    	echo false;
    }
    ddd( $results);

    gracias por la ayuda! 😉

Viendo 9 respuestas - 1 de 9 (de 9 total)
  • Hola @pablocianes todos los posts del array (534,536,538,540) tienen en postmeta un meta_key y meta_value? prueba con un LEFT JOIN para ver los resultados y/o comprueba directamente para cada ID en la Base de Datos que los cuatro ID estén como publicados.

    Puedes probar las dos consultas (LEFT y RIGHT) independientemente antes de hacer el JOIN para ver cual es el problema de que solo coincida una.

    También te será útil hacer un echo de $sql_query o mucho mejor se tienes activado php debug (xDebug) en el servidor de devel, hacer un debug desde el editor y ver los valores de cada variable, con eso seguro que resuelves la consulta en minutos, si tienes algún problema dime y lo miramos con un ejemplo para que pueda probar.

    Gracias Carlos!
    Lo curioso es que si en primer lugar del array pongo por ejemplo el 536 me sale bien la consulta pero sólo con este, y lo mismo si pongo cualquier otro en primera posición del array.
    Con LEFT y RIGHT mismos resultados.

    El echo de la consulta es efectivamente erroneo con sólo un ID dentro del IN:
    SELECT p.post_title AS titulo, p.post_content AS contenido, pm.meta_key, pm.meta_value
    FROM wp_posts AS p
    RIGHT JOIN wp_postmeta AS pm ON (p.ID = pm.post_id)
    WHERE p.post_status = ‘publish’ AND p.post_type = ‘plugins’ AND pm.post_id IN (536) AND pm.meta_key LIKE ‘_url_plugin_%’ ;

    Ups! Al poner IN(%d) tengo errata ya que tiene que ser IN(%s) xD!

    La consulta ahora sale bien con todo el array:
    SELECT p.post_title AS titulo, p.post_content AS contenido, pm.meta_key, pm.meta_value
    FROM wp_posts AS p
    RIGHT JOIN wp_postmeta AS pm ON (p.ID = pm.post_id)
    WHERE p.post_status = ‘publish’ AND p.post_type = ‘plugins’ AND pm.post_id IN (‘536,534,538,540’) AND pm.meta_key LIKE ‘_url_plugin_%’ ;

    pero sigue sin funcionar e idénticos resultados…

    Si pones %s el valor será convertido a un cadena (string) y con %d a entero https://secure.php.net/manual/es/function.sprintf.php pero para la sentencia IN debes pasar los valores separados por comas, si van entre comillas se considerarán una cadena por lo que debería ser:

    
    SELECT p.post_title AS titulo, p.post_content AS contenido, pm.meta_key, pm.meta_value
    FROM wp_posts AS p
    RIGHT JOIN wp_postmeta AS pm ON (p.ID = pm.post_id)
    WHERE p.post_status = 'publish' AND p.post_type = 'plugins' AND pm.post_id IN (536,534,538,540) AND pm.meta_key LIKE '_url_plugin_%';
    

    prueba a ejecutar la consulta sin pasarle el array del IN en el prepara, realizando la sanitización de la variable antes, algo así (código sin probar ya que no tengo esos datos):

    
    $id_plugins = implode( ',', array( 534, 536, 538, 540 ) );  
    global $wpdb;
    $sql_query =
    "SELECT p.post_title AS titulo, p.post_content AS contenido, 
    pm.meta_key, pm.meta_value
    FROM {$wpdb->posts} AS p
    INNER JOIN {$wpdb->postmeta} AS pm ON (p.ID = pm.post_id)
    WHERE p.post_status = 'publish' AND p.post_type = %s AND pm.post_id IN ({$id_plugins}) AND pm.meta_key LIKE %s ;";
    
    $sql_query = $wpdb->prepare( $sql_query, 'plugins', '_url_plugin_%' );
    $results = $wpdb->get_results( $sql_query );
    if ( ! $results || ! is_array( $results ) ) {
    	echo false;
    }
    ddd( $results);
    

    Y me muestra los resultados:

    SQL en HeidiSQL

    Gracias Carlos, me estaba dando cuenta del error pero no conseguía solucionarlo por estar empeñado en usar el “prepare”, ya que si no lo usaba sí que me funcionaba.

    Al final lo voy a dejar como dices evitando el %s y colocando {$id_plugins} dentro del IN

    Muy agradecido por tu tiempo para ayudarme, gracias!;-)

    De nada Pablo, el problema es que pasarle al prepare un string de ids concatenados… vamos que lo mejor tratas el $id_plugins y después lo incluyes en la consulta sin el prepare en este caso.

    Cualquier cosa ya sabes donde localizarme 😉

Viendo 9 respuestas - 1 de 9 (de 9 total)
  • Debes estar registrado para responder a este tema.