2009-03-12 4 views
233

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

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

Можно ли сделать что-то как это?

+2

Этот блог может быть полезен: http://winashwin.wordpress.com/2012/08/28/mysql-search/ – 2012-08-29 04:47:17

ответ

61

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

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

+32

Это не тот ответ, который я хотел, но я должен принять правду. : D Спасибо – RSilva

+1

Это правильно, но ответ @Dan Rather тоже помог, потому что db, который я просматривал, был настроен неясно, и я не мог понять, какое имя столбца или таблица будет точно, просто посмотрев ... – DrCord

+11

'information_schema' - это база данных, а не таблица. Некоторое уточнение, по какой таблице искать в 'information_schema' было бы хорошо! – CaptSaltyJack

2

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

SHOW TABLES; 

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

SHOW COLUMNS FROM table; 

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

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

+0

'SHOW TABLES FROM ' более точно – vladkras

40

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

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

+1

это очень полезно. : D – gumuruh

+0

Может быть полезным скриптом, к сожалению, не работает. –

+0

спасибо, очень полезный и работающий очень хорошо –

159

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

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

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

+5

Одна из наших баз данных - 92.7Gb, и этот параметр работал отлично. Отличное решение – Tricky

+4

Я всегда забываю, что может сделать все phpMyAdmin. Это отличный инструмент! – Ville

+0

Его отличный инструмент. Это очень помогает мне ... – user2727841

374

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

+8

+1 Да, это так просто! Это то, что мне нужно! –

+0

+1 Такая простая идея, и я не думал об этом. Хороший ответ. –

+16

Не забывайте, что вы можете использовать флаг --extended-insert = FALSE для mysqldump, чтобы сделать вывод более читаемым. – Benubird

2

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

6

Это самый простой запрос, чтобы retrive все столбцы и таблицы

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

Все таблицы или те с определенной строки в имени может осуществлять поиск с помощью поисковой вкладки в PhpMyAdmin.

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

+10

и как насчет значений? – themis

39
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; 
} 
+3

ИМХО это должен был быть принятый ответ. – aggregate1166877

+4

Это хорошо, но я бы предпочел чистое SQL-решение ... – Chonez

+1

Это очень хороший код, нужна некоторая работа над структурой вывода, но, безусловно, он делает то, что ему нужно. Я помещаю это на php скрипку со всей программой php и готов к использованию http: //sandbox.onlinephpfunctions.com/code/f2455aada0424c0885c604110dc3c17892f18a4d – pal4life

4

Вот мое решение этой

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; 
+1

Когда я запускаю 'CALL findAll ('tbl_test', 'abb')', я пропущу эту ошибку: ** # 1267 - Недопустимое сочетание сортировок (utf8_general_ci, IMPLICIT) и (utf8_unicode_ci, IMPLICIT) для operation '=' ** Вы можете исправить это? Благодаря! – Davuz

2

Это решение
а) только MySQL, ни один другой язык нужен, и
б) возвращает результаты 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; 
+0

Для таких решений, обычно добавляющих их в phpfiddler, было бы хорошо, поэтому люди могут взглянуть и даже прокомментировать ваше решение. :) – pal4life

+0

Я получаю ошибку '# 1243 - Неизвестный подготовленный обработчик инструкции (stmt), данный EXECUTE', когда я запускаю ваш запрос в Phpmyadmin для поиска во всей базе данных –

+0

@VickyDev Я знаю, что прошло больше года с вашего вопроса. Сожалею. Тем не менее: я думаю, что в вашем скрипте что-то не так, так как stmt объявлен в строке выше EXECUTE. Какую версию MySQL вы используете? – Chonez

8

Я тоже мой собственный 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: [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] 
+0

Я получаю эту ошибку: Неустранимая ошибка: Не удалось исключить «PDOException» с сообщением «SQLSTATE [42000]: Ошибка синтаксиса или нарушение доступа: 1064 У вас есть ошибка в синтаксисе SQL; проверьте руководство, соответствующее версии вашего сервера MySQL, для правильного синтаксиса для использования рядом с клавишей LIKE REPLACE (ЗАМЕНИТЬ (ЗАМЕНИТЬ (ЗАМЕНИТЬ (ЗАМЕНИТЬ ('180well *', '\\', '\\\\'), '% ',' в строке 1 ' – LLBBL

2

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

2

Я отредактировал PHP-ответ Оливье немного:

  • распечатать результаты, в которых строка была f ound
  • опускает таблицу без результатов
  • также показывают выход, если имена столбцов Сопрягайте Поиск Введите
  • показать общее количество результатов

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

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

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

+0

+1 Кажется, что это хорошо работает, и это полезный инструмент, который помогает избежать проблем, связанных с некоторыми другими ответами. Также стоит отметить, что он позволяет вам выбирать, какие базы данных искать в –

0

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

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

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

Щелкните правой кнопкой мыши по вашей схеме и «Поиск данных таблицы», введите свое значение и нажмите «Начать поиск». Это оно.

7

Если вы избегаете 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 или DB, если необходимо, или для выполнения заявлений 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

WARNING: DO NOT RUN THIS IF:

  1. You are concerned with causing Table-locks (keep an eye on your client-connections)
  2. You are unsure what you are doing.

  3. You are trying to anger you DBA. (you may have people at your desk with the quickness.)

Cheers, Джей; -]

+1

Определенно не то, что вы хотите запустить на live db, но полезно для определенных задач отладки. Это не удается, если тип столбца не сравнивается с строкой. То есть столбец int. –

+0

Отличный момент, я добавил три альтернативы поиску thru blobs, chars или ints. Это всего лишь обобщение и ВСЕГДА следует использовать с ПРЕДОСТЕРЕЖЕНИЕМ. НИКОГДА НА ПРОДУКЦИЮ, как вы упомянули, это обычно то, что вас уволило «Поиск сценариев в Интернете и не понимание их, но все же их ", но, эй, это то, как люди узнают трудно. – JayRizzo

1

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

+0

Не лучший способ архивировать то, что он хочет – Jacky

0

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

} 
0

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

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

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

Смежные вопросы