¿Cómo puedo consultar simultáneamente todas las tablas de opciones del blog en una instalación multisitio de WordPress (3.0)?

3 minutos de lectura

avatar de usuario
michael henretty

En nuestra instalación multisitio de WordPress 3.0, tenemos una opción personalizada para todos nuestros blogs llamada algo así como ‘plataforma’. Los administradores pueden ingresar un valor para esta plataforma al crear o editar un blog. Algunos blogs pueden no tener plataforma.

Necesitamos poder crear una lista de todas las plataformas y sus blogs asociados. El problema es que creamos y eliminamos blogs dinámicamente a través de otros mecanismos del sitio, por lo que tenemos muchas tablas de opciones de blog con números que no son necesariamente contiguos. (es decir, wp_2_options, wp_4_options, wp_12_options, etc.)

Mi pregunta es esta, ¿hay alguna forma en WordPress de obtener una opción en todos los blogs? Por el contrario, ¿hay alguna consulta que pueda ejecutar que haga esto manualmente? He intentado algo como esto sin ningún efecto:

SELECCIONE * DESDE (SELECCIONE nombre_tabla DESDE esquema_información.tablas DONDE nombre_tabla como ‘wp_%_options’) como t DONDE nombre_opción=”plataforma”

¿Tiene sentido lo que estoy tratando de hacer? Nuevamente, pido disculpas por mi falta de conocimiento de MySql, pero no he podido encontrar ninguna respuesta sobre cómo hacer esto. También podría consultar todos estos nombres de tablas primero y luego consultar cada tabla por separado, pero esa no es realmente una opción porque tenemos muchos blogs, y es posible que necesitemos ejecutar esta consulta para muchas solicitudes de página simultáneamente, y esto agregaría cientos de consultas a cada una de estas solicitudes.

Cualquier consejo o ayuda que ustedes puedan dar sería muy apreciado.

En caso de que alguien esté interesado, terminé haciéndolo así (pero aún me gustaría saber si es posible hacer una búsqueda en los nombres de las tablas usando LIKE y luego consultar esas tablas, si alguien sabe).

// so get all the blog ids from the blogs table
$blogs = $wpdb->get_results("SELECT blog_id FROM {$wpdb->blogs}", ARRAY_A);

// build a sql statement for each blog options table, adding in the blog id for each row
$select_statements = array();
foreach ($blogs as $blog_row) {
    $select_statements[] = 'SELECT option_value, CAST( '.$blog_row['blog_id'].' AS UNSIGNED INTEGER ) AS blog_id FROM '.$wpdb->get_blog_prefix($blog_row['blog_id'])."options WHERE option_name="$option_name"";
}

// cache the results of the union of all these select statements
$option_results = $wpdb->get_results(implode(' UNION ALL ', $select_statements), ARRAY_A);

  • gracias por esto. ¿Sabes cómo puedes consultar múltiples opciones?

    – Alex

    16 de enero de 2011 a las 5:45

  • Hmmm, creo que todo lo que tendría que hacer es cambiar la cláusula WHERE de sus consultas internas. Algo como: “… DONDE option_name=’$option_name1′ OR option_name=’$option_name2′”; … También podría usar MYSQL IN clase “… WHERE option_name IN (‘$option_name1’, ‘$option_name2’)” ¡Espero que eso ayude!

    – Michael Henretty

    19 de enero de 2011 a las 22:05


Si desea consultar directamente la base de datos MySQL, puede crear un procedimiento y usarlo:

use wordpress;
Drop Procedure IF EXISTS wordpress.MyProcedure;
DELIMITER | ;
CREATE PROCEDURE MyProcedure (param1 VARCHAR(30))
BEGIN
        DECLARE tbname CHAR(50);
        DECLARE endfetch INT DEFAULT 0;
        DECLARE cur1 CURSOR FOR 
        SELECT table_name FROM information_schema.tables WHERE table_schema="wordpress" and table_name like '%options';
        DECLARE CONTINUE HANDLER FOR SQLSTATE '02000'
                SET endfetch = 1;
        OPEN cur1;
        FETCH cur1 INTO tbname;
        fetchloop: WHILE NOT endfetch DO
            SELECT tbname ; 
            SET @opt = param1;
            SET @table_name = tbname;
            SET @sql_text = concat('SELECT option_value FROM ',@table_name,' WHERE option_name=""',@opt,'''');
            PREPARE stmt FROM @sql_text;
            EXECUTE stmt;
            DEALLOCATE PREPARE stmt;

            FETCH cur1 INTO tbname;
        END WHILE fetchloop;
END
|
DELIMITER ; |


CALL MyProcedure('siteurl');

¿Ha sido útil esta solución?