Я хочу искать во всех полях из всех таблиц базы данных MySQL заданную строку, возможно используя синтаксис как:
SELECT * FROM * WHERE * LIKE '%stuff%'
Можно ли сделать что-то подобное?
Я хочу искать во всех полях из всех таблиц базы данных MySQL заданную строку, возможно используя синтаксис как:
SELECT * FROM * WHERE * LIKE '%stuff%'
Можно ли сделать что-то подобное?
Вы можете заглянуть в схему information_schema
. Он содержит список всех таблиц и всех полей, которые находятся в таблице. Затем вы можете запускать запросы, используя информацию, полученную из этой таблицы.
В таблицах участвуют SCHEMATA, TABLES и COLUMNS. Существуют внешние ключи, так что вы можете точно определить, как таблицы создаются в схеме.
Вы можете сделать SQLDump
базы данных (и ее данных), затем выполнить поиск этого файла.
Если у вас установлен phpMyAdmin, используйте его функцию "Поиск".
Я использовал это до 250 табличных /10 ГБ баз данных (на быстром сервере), а время отклика - не что иное, как удивительное.
function searchAllDB($search){
global $mysqli;
$out = "";
$sql = "show tables";
$rs = $mysqli->query($sql);
if($rs->num_rows > 0){
while($r = $rs->fetch_array()){
$table = $r[0];
$out .= $table.";";
$sql_search = "select * from ".$table." where ";
$sql_search_fields = Array();
$sql2 = "SHOW COLUMNS FROM ".$table;
$rs2 = $mysqli->query($sql2);
if($rs2->num_rows > 0){
while($r2 = $rs2->fetch_array()){
$colum = $r2[0];
$sql_search_fields[] = $colum." like('%".$search."%')";
}
$rs2->close();
}
$sql_search .= implode(" OR ", $sql_search_fields);
$rs3 = $mysqli->query($sql_search);
$out .= $rs3->num_rows."\n";
if($rs3->num_rows > 0){
$rs3->close();
}
}
$rs->close();
}
return $out;
}
Вы можете использовать этот проект: http://code.google.com/p/anywhereindb
Это приведет к поиску всех данных во всей таблице.
Если вы избегаете stored procedures
, как чума, или не можете сделать mysql_dump
из-за разрешений или сталкиваетесь с другими различными причинами.
Я бы предложил трехэтапный подход, подобный следующему:
1) Где этот запрос строит группу запросов в качестве результирующего набора.
# =================
# VAR/CHAR SEARCH
# =================
# BE ADVISED USE ANY OF THESE WITH CAUTION
# DON'T RUN ON YOUR PRODUCTION SERVER
# ** USE AN ALTERNATE BACKUP **
SELECT
CONCAT('SELECT * FROM ', A.TABLE_SCHEMA, '.', A.TABLE_NAME,
' WHERE ', A.COLUMN_NAME, ' LIKE \'%stuff%\';')
FROM INFORMATION_SCHEMA.COLUMNS A
WHERE
A.TABLE_SCHEMA != 'mysql'
AND A.TABLE_SCHEMA != 'innodb'
AND A.TABLE_SCHEMA != 'performance_schema'
AND A.TABLE_SCHEMA != 'information_schema'
AND
(
A.DATA_TYPE LIKE '%text%'
OR
A.DATA_TYPE LIKE '%char%'
)
;
.
# =================
# NUMBER SEARCH
# =================
# BE ADVISED USE WITH CAUTION
SELECT
CONCAT('SELECT * FROM ', A.TABLE_SCHEMA, '.', A.TABLE_NAME,
' WHERE ', A.COLUMN_NAME, ' IN (\'%1234567890%\');')
FROM INFORMATION_SCHEMA.COLUMNS A
WHERE
A.TABLE_SCHEMA != 'mysql'
AND A.TABLE_SCHEMA != 'innodb'
AND A.TABLE_SCHEMA != 'performance_schema'
AND A.TABLE_SCHEMA != 'information_schema'
AND A.DATA_TYPE IN ('bigint','int','smallint','tinyint','decimal','double')
;
.
# =================
# BLOB SEARCH
# =================
# BE ADVISED THIS IS CAN END HORRIFICALLY IF YOU DONT KNOW WHAT YOU ARE DOING
# YOU SHOULD KNOW IF YOU HAVE FULL TEXT INDEX ON OR NOT
# MISUSE AND YOU COULD CRASH A LARGE SERVER
SELECT
CONCAT('SELECT CONVERT(',A.COLUMN_NAME, ' USING utf8) FROM ', A.TABLE_SCHEMA, '.', A.TABLE_NAME,
' WHERE CONVERT(',A.COLUMN_NAME, ' USING utf8) IN (\'%someText%\');')
FROM INFORMATION_SCHEMA.COLUMNS A
WHERE
A.TABLE_SCHEMA != 'mysql'
AND A.TABLE_SCHEMA != 'innodb'
AND A.TABLE_SCHEMA != 'performance_schema'
AND A.TABLE_SCHEMA != 'information_schema'
AND A.DATA_TYPE LIKE '%blob%'
;
Результаты должны выглядеть следующим образом:
2) Затем вы можете просто Right Click
и использовать Copy Row (tab-separated)
3) Вставьте результаты в новое окно запроса и запустите к своему сердцу содержание.
Подробно: я исключаю системную схему, которую вы обычно не видите в своем рабочем месте, если у вас не установлен флажок Show Metadata and Internal Schemas
.
Я сделал это, чтобы обеспечить быстрый способ ANALYZE
целого HOST или БД, если необходимо, или запустить операторы OPTIMIZE
для поддержки повышения производительности.
Я уверен, что есть разные способы сделать это, но вот что работает для меня:
-- ========================================== DYNAMICALLY FIND TABLES AND CREATE A LIST OF QUERIES IN THE RESULTS TO ANALYZE THEM
SELECT CONCAT('ANALYZE TABLE ', TABLE_SCHEMA, '.', TABLE_NAME, ';') FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'dbname';
-- ========================================== DYNAMICALLY FIND TABLES AND CREATE A LIST OF QUERIES IN THE RESULTS TO OPTIMIZE THEM
SELECT CONCAT('OPTIMIZE TABLE ', TABLE_SCHEMA, '.', TABLE_NAME, ';') FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'dbname';
Tested On MySQL Version: 5.6.23
ВНИМАНИЕ: НЕ ПУТЕШЕСТВОВАТЬ, ЕСЛИ:
- Вы озабочены тем, чтобы вызывать блокировки таблиц (следите за вашими клиентскими подключениями)
Вы не уверены, что делаете.
Вы пытаетесь разозлить вас, администратор БД. (у вас могут быть люди за столом с быстротой.)
Ура, Джей; -]
Я также выполнил свой собственный искатель mysql для поиска некоторой конфигурации wordpress, не смог найти его как в интерфейсе, так и в базе данных, а дампы базы данных были слишком тяжелыми и нечитаемыми. Я должен сказать, что теперь я не могу обойтись без этого.
Он работает как один из @Olivier, но он управляет экзотическими именами базы данных/таблиц и безопасен LIKE-joker.
<?php
$database = 'database';
$criteria = '*iemblo'; // you can use * and ? as jokers
$dbh = new PDO("mysql:host=127.0.0.1;dbname={$database};charset=utf8", 'root', '');
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$tables = $dbh->query("SHOW TABLES");
while (($table = $tables->fetch(PDO::FETCH_NUM)) !== false)
{
$fields = $dbh->prepare("SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = ? AND TABLE_NAME = ?");
$fields->execute(array ($database, $table[0]));
$ors = array ();
while (($field = $fields->fetch(PDO::FETCH_NUM)) !== false)
{
$ors[] = str_replace("`", "``", $field[0]) . " LIKE REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(:search, '\\\\', '\\\\\\\\'), '%', '\\%'), '_', '\\_'), '*', '%'), '?', '_')";
}
$request = 'SELECT * FROM ';
$request .= str_replace("`", "``", $table[0]);
$request .= ' WHERE ';
$request .= implode(' OR ', $ors);
$rows = $dbh->prepare($request);
$rows->execute(array ('search' => $criteria));
$count = $rows->rowCount();
if ($count == 0)
{
continue;
}
$str = "Table '{$table[0]}' contains {$count} rows matching '{$criteria}'.";
echo str_repeat('-', strlen($str)), PHP_EOL;
echo $str, PHP_EOL;
echo str_repeat('-', strlen($str)), PHP_EOL;
$counter = 1;
while (($row = $rows->fetch(PDO::FETCH_ASSOC)) !== false)
{
$col = 0;
$title = "Row #{$counter}:";
echo $title;
foreach ($row as $column => $value)
{
echo
(($col++ > 0) ? str_repeat(' ', strlen($title) + 1) : ' '),
$column, ': ',
trim(preg_replace('!\s+!', ' ', str_replace(array ("\r", "\t", "\n"), array ("", "", " "), $value))),
PHP_EOL;
}
echo PHP_EOL;
$counter++;
}
}
Запуск этого script может выводить что-то вроде:
---------------------------------------------------
Table 'customers' contains 1 rows matching '*iemblo'.
---------------------------------------------------
Row #1: email_client: [email protected]
numero_client_compta: C05135
nom_client: Tiemblo
adresse_facturation_1: 151, My Street
adresse_facturation_2:
ville_facturation: Nantes
code_postal_facturation: 44300
pays_facturation: FR
numero_tva_client:
zone_geographique: UE
prenom_client: Alain
commentaires:
nom_societe:
email_facturation: [email protected]
Это самый простой запрос для извлечения всех столбцов и таблиц
SELECT * FROM information_schema.`COLUMNS` C WHERE TABLE_SCHEMA = 'YOUR_DATABASE'
Все таблицы или те, у которых определенная строка в имени, могут быть найдены через вкладку "Поиск" в phpMyAdmin.
Иметь хороший запрос... \^. ^/
С помощью MySQL Workbench легко выбрать несколько таблиц и выполнить поиск текста во всех этих таблицах БД: -)
Вот мое решение для этого
DROP PROCEDURE IF EXISTS findAll;
CREATE PROCEDURE `findAll`( IN `tableName` VARCHAR( 28 ) , IN `search` TEXT )
BEGIN
DECLARE finished INT DEFAULT FALSE ;
DECLARE columnName VARCHAR ( 28 ) ;
DECLARE stmtFields TEXT ;
DECLARE columnNames CURSOR FOR
SELECT DISTINCT `COLUMN_NAME` FROM `information_schema`.`COLUMNS`
WHERE `TABLE_NAME` = tableName ORDER BY `ORDINAL_POSITION` ;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET finished = TRUE;
SET stmtFields = '' ;
OPEN columnNames ;
readColumns: LOOP
FETCH columnNames INTO columnName ;
IF finished THEN
LEAVE readColumns ;
END IF;
SET stmtFields = CONCAT(
stmtFields , IF ( LENGTH( stmtFields ) > 0 , ' OR' , '' ) ,
' `', tableName ,'`.`' , columnName , '` REGEXP "' , search , '"'
) ;
END LOOP;
SET @stmtQuery := CONCAT ( 'SELECT * FROM `' , tableName , '` WHERE ' , stmtFields ) ;
PREPARE stmt FROM @stmtQuery ;
EXECUTE stmt ;
CLOSE columnNames ;
END;
Я использую HeidiSQL - полезный и надежный инструмент, предназначенный для веб-разработчиков с использованием популярного сервера MySQL.
В HeidiSQL вы можете нажать shift + ctrl + f, и вы можете найти текст на сервере во всех таблицах. Этот параметр очень полезен.
Хотя этот вопрос старый, вот как это сделать, если вы используете mysql workbench 6.3. (Скорее всего, он также работает и для других версий)
Щелкните правой кнопкой мыши вашу схему и "Данные таблицы поиска", введите свое значение и нажмите "Начать поиск". Вот оно.
Это простой способ, который я знаю. Выберите свою БД в PHPMyAdmin и перейдите на вкладку "Поиск" и напишите, что вы хотите найти и где вы будете искать. Выберите все таблицы, если вы будете искать слова из всех таблиц. Тогда "ИДТИ" и посмотрите результат.
Вы можете использовать
SHOW TABLES;
Затем получите столбцы в этих таблицах (в цикле) с помощью
SHOW COLUMNS FROM table;
а затем с этой информацией создайте много запросов, которые вы также можете использовать UNION, если вам нужно.
Но это очень тяжело для базы данных. Специально, если вы делаете LIKE-поиск.
Это решение
а) это только MySQL, не нужен другой язык, и
b) возвращает результаты SQL, готовые к обработке!
#Search multiple database tables and/or columns
#Version 0.1 - JK 2014-01
#USAGE: 1. set the search term @search, 2. set the scope by adapting the WHERE clause of the `information_schema`.`columns` query
#NOTE: This is a usage example and might be advanced by setting the scope through a variable, putting it all in a function, and so on...
#define the search term here (using rules for the LIKE command, e.g % as a wildcard)
SET @search = '%needle%';
#settings
SET SESSION group_concat_max_len := @@max_allowed_packet;
#ini variable
SET @sql = NULL;
#query for prepared statement
SELECT
GROUP_CONCAT("SELECT '",`TABLE_NAME`,"' AS `table`, '",`COLUMN_NAME`,"' AS `column`, `",`COLUMN_NAME`,"` AS `value` FROM `",TABLE_NAME,"` WHERE `",COLUMN_NAME,"` LIKE '",@search,"'" SEPARATOR "\nUNION\n") AS col
INTO @sql
FROM `information_schema`.`columns`
WHERE TABLE_NAME IN
(
SELECT TABLE_NAME FROM `information_schema`.`columns`
WHERE
TABLE_SCHEMA IN ("my_database")
&& TABLE_NAME IN ("my_table1", "my_table2") || TABLE_NAME LIKE "my_prefix_%"
);
#prepare and execute the statement
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
Сбрасывание файла SQL, вероятно, было самым быстрым и быстрым для меня. Также в любом случае обнаружена другая проблема.
Я немного изменил PHP-ответ Оливье:
показать общее количество результатов
function searchAllDB($search){
global $mysqli;
$out = "";
$total = 0;
$sql = "SHOW TABLES";
$rs = $mysqli->query($sql);
if($rs->num_rows > 0){
while($r = $rs->fetch_array()){
$table = $r[0];
$sql_search = "select * from ".$table." where ";
$sql_search_fields = Array();
$sql2 = "SHOW COLUMNS FROM ".$table;
$rs2 = $mysqli->query($sql2);
if($rs2->num_rows > 0){
while($r2 = $rs2->fetch_array()){
$colum = $r2[0];
$sql_search_fields[] = $colum." like('%".$search."%')";
if(strpos($colum,$search))
{
echo "FIELD NAME: ".$colum."\n";
}
}
$rs2->close();
}
$sql_search .= implode(" OR ", $sql_search_fields);
$rs3 = $mysqli->query($sql_search);
if($rs3 && $rs3->num_rows > 0)
{
$out .= $table.": ".$rs3->num_rows."\n";
if($rs3->num_rows > 0){
$total += $rs3->num_rows;
$out.= print_r($rs3->fetch_all(),1);
$rs3->close();
}
}
}
$out .= "\n\nTotal results:".$total;
$rs->close();
}
return $out;
}
Я построил на предыдущем ответе и получил это, дополнительное дополнение, чтобы иметь возможность удобно соединить все выходные данные:
SELECT
CONCAT('SELECT ''',A.TABLE_NAME, '-' ,A.COLUMN_NAME,''' FROM ', A.TABLE_SCHEMA, '.', A.TABLE_NAME,
' WHERE ', A.COLUMN_NAME, ' LIKE \'%Value%\' UNION')
FROM INFORMATION_SCHEMA.COLUMNS A
WHERE
A.TABLE_SCHEMA != 'mysql'
AND A.TABLE_SCHEMA != 'innodb'
AND A.TABLE_SCHEMA != 'performance_schema'
AND A.TABLE_SCHEMA != 'information_schema'
UNION SELECT 'SELECT '''
-- for exact match use: A.COLUMN_NAME, ' LIKE \'Value\' instead
Сначала вы запустите это, затем вставьте и запустите результат (без редактирования), и он отобразит все имена таблиц и столбцы, в которых используется значение.
Я получил это, чтобы работать. вам просто нужно изменить переменные
$query ="SELECT 'column_name' FROM 'information_schema'.'columns' WHERE 'table_schema'='" . $_SESSION['db'] . "' AND 'table_name'='" . $table . "' ";
$stmt = $dbh->prepare($query);
$stmt->execute();
$columns = $stmt->fetchAll(PDO::FETCH_ASSOC);
$query="SELECT name FROM '" . $database . "'.'" . $table . "' WHERE ( ";
foreach ( $columns as $column ) {
$query .=" CONVERT( '" . $column['column_name'] . "' USING utf8 ) LIKE '%" . $search . "%' OR ";
}
$query = substr($query, 0, -3);
$query .= ")";
echo $query . "<br>";
$stmt=$dbh->prepare($query);
$stmt->execute();
$results = $stmt->fetchAll(PDO::FETCH_ASSOC);
echo "<pre>";
print_r ($results );
echo "</pre>";
Я использовал Union для объединения запросов. Не знаю, эффективен ли он, но он работает.
SELECT * FROM table1 WHERE name LIKE '%Bob%' Union
SELCET * FROM table2 WHERE name LIKE '%Bob%';
Существует хорошая библиотека для чтения всех таблиц, ridona
$database = new ridona\Database('mysql:dbname=database_name;host=127.0.0.1', 'db_user','db_pass');
foreach ($database->tables()->by_entire() as $row) {
....do
}
Я не знаю, действительно ли это только в последних версиях, но при нажатии правой кнопки мыши на вкладке " Tables
на панели " Navigator
появляется опция " Search Table Data
. Это открывает окно поиска, в котором вы заполняете строку поиска и нажимаете поиск.
Вам нужно выбрать таблицу, которую вы хотите найти, на левой панели. Но если вы удерживаете сдвиг и выбираете 10 таблиц за раз, MySql может справиться с этим и вернуть результаты за считанные секунды.
Для тех, кто ищет лучшие варианты! :)
Я сделал это с помощью HeidiSQL. Это не легко найти, но нажав Ctrl + Shift + F, он отображает диалог "инструменты таблицы". Затем выберите то, что вы хотите найти (от полной базы данных до одной таблицы), введите значение "Текст для поиска" и нажмите "Найти". Я нашел это удивительно быстро (870MB дБ менее чем за минуту)
Если вы используете phpMyAdmin
следуйте этому ответу, на этом сайте эта ссылка.
Экспортировать всю базу данных и искать в файле .sql.