Искать во всех полях из каждой таблицы базы данных MySQL

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

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

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

Ответ 1

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

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

Ответ 2

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

Ответ 3

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

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

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

Ответ 4

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

Ответ 5

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

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

Ответ 6

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

Tested On MySQL Version: 5.6.23

ВНИМАНИЕ: НЕ ПУТЕШЕСТВОВАТЬ, ЕСЛИ:

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

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

Ура, Джей; -]

Ответ 7

Я также выполнил свой собственный искатель 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]

Ответ 8

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

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

Все таблицы или те, у которых определенная строка в имени, могут быть найдены через вкладку "Поиск" в phpMyAdmin.

Иметь хороший запрос... \^. ^/

Ответ 9

С помощью MySQL Workbench легко выбрать несколько таблиц и выполнить поиск текста во всех этих таблицах БД: -)

Ответ 10

Вот мое решение для этого

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;

Ответ 11

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

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

Ответ 12

Хотя этот вопрос старый, вот как это сделать, если вы используете mysql workbench 6.3. (Скорее всего, он также работает и для других версий)

Щелкните правой кнопкой мыши вашу схему и "Данные таблицы поиска", введите свое значение и нажмите "Начать поиск". Вот оно.

Ответ 13

Это простой способ, который я знаю. Выберите свою БД в PHPMyAdmin и перейдите на вкладку "Поиск" и напишите, что вы хотите найти и где вы будете искать. Выберите все таблицы, если вы будете искать слова из всех таблиц. Тогда "ИДТИ" и посмотрите результат. I Want to find the word VCD (backdoor) from my Wordpress DB for deleting

Ответ 14

Вы можете использовать

SHOW TABLES;

Затем получите столбцы в этих таблицах (в цикле) с помощью

SHOW COLUMNS FROM table;

а затем с этой информацией создайте много запросов, которые вы также можете использовать UNION, если вам нужно.

Но это очень тяжело для базы данных. Специально, если вы делаете LIKE-поиск.

Ответ 15

Это решение
а) это только 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;

Ответ 16

Сбрасывание файла SQL, вероятно, было самым быстрым и быстрым для меня. Также в любом случае обнаружена другая проблема.

Ответ 17

Я немного изменил 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;
    }
    

Ответ 18

Я построил на предыдущем ответе и получил это, дополнительное дополнение, чтобы иметь возможность удобно соединить все выходные данные:

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

Сначала вы запустите это, затем вставьте и запустите результат (без редактирования), и он отобразит все имена таблиц и столбцы, в которых используется значение.

Ответ 19

Я получил это, чтобы работать. вам просто нужно изменить переменные

$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>";

Ответ 20

Я использовал Union для объединения запросов. Не знаю, эффективен ли он, но он работает.

SELECT * FROM table1 WHERE name LIKE '%Bob%' Union
SELCET * FROM table2 WHERE name LIKE '%Bob%';

Ответ 21

Существует хорошая библиотека для чтения всех таблиц, 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

}

Ответ 22

Я не знаю, действительно ли это только в последних версиях, но при нажатии правой кнопки мыши на вкладке " Tables на панели " Navigator появляется опция " Search Table Data. Это открывает окно поиска, в котором вы заполняете строку поиска и нажимаете поиск.

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

Для тех, кто ищет лучшие варианты! :)

Ответ 23

Я сделал это с помощью HeidiSQL. Это не легко найти, но нажав Ctrl + Shift + F, он отображает диалог "инструменты таблицы". Затем выберите то, что вы хотите найти (от полной базы данных до одной таблицы), введите значение "Текст для поиска" и нажмите "Найти". Я нашел это удивительно быстро (870MB дБ менее чем за минуту)

Ответ 25

Экспортировать всю базу данных и искать в файле .sql.