Перечисление таблиц, используемых в запросе mysql?
Вопрос
Есть ли какой-нибудь способ перечислить таблицы, используемые в запросе mysql?
Допустим, у меня есть запрос :
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
И я хочу, чтобы в ответ был массив:
$tables = array(
[0] => 'db_people.people_facts',
[1] => 'db_system.connections',
[2] => 'db_people.people',
);
Решение
Решение, отмеченное как хорошее, вернет только таблицы результатов.Но если вы выполните следующий запрос, он завершится неудачей:
SELECT users.* FROM users, cats, dogs WHERE users.id = cats.user_id
Будет возвращать только пользователей и не столы для кошек и собак.
Лучшее решение - найти хороший анализатор, другое решение - использовать РЕГУЛЯРНОЕ выражение и ОБЪЯСНИТЬ запрос (подробнее по следующей ссылке):
Получение таблиц mysql в запросе
Но я думаю, что еще одним хорошим решением является перечислите все таблицы и выполните поиск по ним внутри запроса, вы можете кэшировать список таблиц.
Редактировать:При поиске таблиц лучше использовать прег, подобный:
// (`|'|"| )table_name(\1|$)
if(preg_match('/(`|\'|"| )table_name(\1|$)/i', $query))
// found
Если нет, то он может возвращать ложные срабатывания, например, с "table_name2", "table_name3"...имя_таблицы вернет НАЙДЕННОЕ два раза.
Другие советы
Да, вы можете получить информацию о таблицах и столбцах, которые являются частью результата запроса.Это называется метаданные результирующего набора.
Единственным решением PHP для метаданных результирующего набора MySQL является использование расширения MySQLi и 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";
Вам придется самостоятельно создать массив различных таблиц, используемых в запросе, путем перебора полей.
В зависимости от того, для чего вы его используете, MySQL's EXPLAIN может сделать это за вас: