Поиск по всем полям из каждой таблицы базы данных MySQL - PullRequest
283 голосов
/ 12 марта 2009

Я хочу найти во всех полях из всех таблиц базы данных MySQL заданную строку, возможно, используя синтаксис:

SELECT * FROM * WHERE * LIKE '%stuff%'

Можно ли сделать что-то подобное?

Ответы [ 25 ]

423 голосов
/ 27 января 2011

Вы можете сделать SQLDump базы данных (и ее данных), а затем найти этот файл.

190 голосов
/ 01 октября 2010

Если у вас установлен phpMyAdmin, используйте функцию «Поиск».

  • Выберите вашу базу данных
  • Убедитесь, что у вас выбрана БД (т. Е. Не таблица, иначе вы получите совершенно другой диалог поиска)
  • Нажмите вкладку «Поиск»
  • Выберите искомое условие
  • Выберите таблицы для поиска

Я использовал это до 250 таблиц / 10 ГБ баз данных (на быстром сервере), и время отклика просто удивительно.

79 голосов
/ 12 марта 2009

Вы можете заглянуть в схему information_schema. Он имеет список всех таблиц и всех полей, которые находятся в таблице. Затем вы можете выполнять запросы, используя информацию, полученную из этой таблицы.

Используются таблицы SCHEMATA, TABLES и COLUMNS. Существуют внешние ключи, так что вы можете точно определить, как таблицы создаются в схеме.

42 голосов
/ 08 марта 2011
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;
}
41 голосов
/ 12 мая 2009

Вы можете использовать этот проект: http://code.google.com/p/anywhereindb

Это будет искать все данные во всей таблице.

11 голосов
/ 17 ноября 2016

Если вы избегаете 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%'
;

Результаты должны выглядеть следующим образом:

Copy these results into another query window

2) Затем вы можете просто Right Click и использовать Copy Row (tab separated)

enter image description here

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';

Проверено на версии MySQL: 5.6.23

ПРЕДУПРЕЖДЕНИЕ: НЕ ПРОПУСТИТЕ ЭТО, ЕСЛИ:

  1. Вы озабочены тем, чтобы вызывать блокировки таблиц (следите за вашими клиентскими подключениями)
  2. Вы не уверены, что делаете.

  3. Вы пытаетесь разозлить своего администратора. (на вашем столе могут быть люди с быстротой .)

Ура, Джей; -]

8 голосов
/ 08 октября 2014

Я также сделал свой собственный сканер 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++;
    }
}

Запуск этого скрипта может вывести что-то вроде:

---------------------------------------------------
Table 'customers' contains 1 rows matching '*iemblo'.
---------------------------------------------------
Row #1: email_client: my@email.com
        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: my@email.com
6 голосов
/ 11 февраля 2011

Это самый простой запрос для извлечения всех столбцов и таблиц

SELECT * FROM information_schema.`COLUMNS` C WHERE TABLE_SCHEMA = 'YOUR_DATABASE'

Все таблицы или таблицы с определенной строкой в ​​имени можно найти на вкладке Поиск в phpMyAdmin.

Приятного запроса ... \ ^. ^ /

5 голосов
/ 13 февраля 2016

Я использую HeidiSQL - полезный и надежный инструмент, разработанный для веб-разработчиков, использующих популярный сервер MySQL.

В HeidiSQL вы можете нажать shift + ctrl + f, и вы можете найти текст на сервере во всех таблицах. Эта опция очень полезна.

5 голосов
/ 14 сентября 2015

Используя MySQL Workbench, легко выбрать несколько таблиц и запустить поиск текста во всех этих таблицах БД; -)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...