¿Enumerar tablas utilizadas en consultas MySQL?
Pregunta
¿Hay alguna forma de enumerar las tablas utilizadas en la consulta MySQL?
Digamos que tengo una consulta:
SELECT * FROM db_people.people_facts pf
INNER JOIN db_system.connections sm ON sm.source_id = pf.object_id
INNER JOIN db_people.people p ON sm.target_id = p.object_id
ORDER BY pf.object_id DESC
Y quiero a cambio una matriz:
$tables = array(
[0] => 'db_people.people_facts',
[1] => 'db_system.connections',
[2] => 'db_people.people',
);
Solución
La solución marcada como buena devolverá solo las tablas de resultados.Pero si realiza la siguiente consulta, fallará:
SELECT users.* FROM users, cats, dogs WHERE users.id = cats.user_id
Voluntad devolver solo usuarios y no mesas para perros y gatos.
La mejor solución es encontrar un buen analizador, otra solución es utilizar la consulta REGEX y EXPLAIN (más información en el siguiente enlace):
Obtener tablas MySQL en una consulta
Pero creo que otra buena solución es enumerar todas las tablas y buscarlas dentro de la consulta, puede almacenar en caché la lista de tablas.
EDITAR:Al buscar tablas, es mejor utilizar un preg como:
// (`|'|"| )table_name(\1|$)
if(preg_match('/(`|\'|"| )table_name(\1|$)/i', $query))
// found
De lo contrario, puede devolver falsos positivos con, por ejemplo, "nombre_tabla2", "nombre_tabla3"...table_name devolverá ENCONTRADO dos veces.
Otros consejos
Sí, se puede obtener información acerca de las tablas y columnas que forman parte del resultado de una consulta. Esto se llama conjunto de resultados metadatos .
La única solución PHP para MySQL conjunto de resultados de metadatos es el uso de la extensión mysqli y la función mysqli_stmt::result_metadata()
.
$stmt = $mysqli->prepare("SELECT * FROM db_people.people_facts pf
INNER JOIN db_system.connections sm ON sm.source_id = pf.object_id
INNER JOIN db_people.people p ON sm.target_id = p.object_id
ORDER BY pf.object_id DESC");
$meta = $stmt->result_metadata();
$field1 = $meta->fetch_field();
echo "Table for field " . $field1->name . " is " . $field1->table . "\n";
Vas a tener que construir el conjunto de tablas distintas utilizadas en la consulta a sí mismo, haciendo un bucle a través de los campos.
En función de lo que se está usando para, MySQL a explicar podría hacer el truco para usted: